IMP logo
IMP Reference Guide  2.7.0
The Integrative Modeling Platform
stereochemistry.py
1 """@namespace IMP.pmi.restraints.stereochemistry
2 Restraints for keeping correct stereochemistry.
3 """
4 
5 from __future__ import print_function
6 import IMP
7 import IMP.core
8 import IMP.algebra
9 import IMP.atom
10 import IMP.container
11 import IMP.isd
12 import itertools
13 import IMP.pmi.tools
15 from operator import itemgetter
16 from math import pi,log,sqrt
17 import sys
18 
19 
20 
21 class ConnectivityRestraint(object):
22  """ This class creates a restraint between consecutive TempResidue objects OR an entire
23  PMI MOlecule object. """
24 
25  def __init__(self,
26  objects,
27  scale=1.0,
28  disorderedlength=False,
29  upperharmonic=True,
30  resolution=1,
31  label="None"):
32  """
33  @param objects - a list of hierarchies, PMI TempResidues OR a single Molecule
34  @param scale Scale the maximal distance between the beads by this factor when disorderedlength is False.
35  The maximal distance is calculated as ((float(residuegap) + 1.0) * 3.6) * scale.
36  @param disorderedlength - This flag uses either disordered length
37  calculated for random coil peptides (True) or zero
38  surface-to-surface distance between beads (False)
39  as optimal distance for the sequence connectivity
40  restraint.
41  @param upperharmonic - This flag uses either harmonic (False)
42  or upperharmonic (True) in the intra-pair
43  connectivity restraint.
44  @param resolution - The resolution to connect things at - only used if you pass PMI objects
45  @param label - A string to identify this restraint in the output/stat file
46  """
47  self.label = label
48  self.weight = 1.0
49 
50  hiers = IMP.pmi.tools.input_adaptor(objects,resolution)
51  if len(hiers)>1:
52  raise Exception("ConnectivityRestraint: only pass stuff from one Molecule, please")
53  hiers = hiers[0]
54 
55  self.kappa = 10 # spring constant used for the harmonic restraints
56  self.m = list(hiers)[0].get_model()
57  SortedSegments = []
58  self.rs = IMP.RestraintSet(self.m, "connectivity_restraint")
59  for h in hiers:
60  try:
61  start = IMP.atom.Hierarchy(h).get_children()[0]
62  except:
63  start = IMP.atom.Hierarchy(h)
64 
65  try:
66  end = IMP.atom.Hierarchy(h).get_children()[-1]
67  except:
68  end = IMP.atom.Hierarchy(h)
69 
70  startres = IMP.pmi.tools.get_residue_indexes(start)[0]
71  endres = IMP.pmi.tools.get_residue_indexes(end)[-1]
72  SortedSegments.append((start, end, startres))
73  SortedSegments = sorted(SortedSegments, key=itemgetter(2))
74 
75  # connect the particles
76  for x in range(len(SortedSegments) - 1):
77 
78  last = SortedSegments[x][1]
79  first = SortedSegments[x + 1][0]
80 
81  apply_restraint = True
82 
83  # Apply connectivity runless ALL of the following are true:
84  # - first and last both have RigidBodyMember decorators
85  # - first and last are both RigidMembers
86  # - first and last are part of the same RigidBody object
87 
88  # Check for both in a rigid body
91 
92  #Check if the rigid body objects for each particle are the same object.
93  # if so, skip connectivity restraint
94  if IMP.core.RigidBodyMember(first).get_rigid_body() == IMP.core.RigidBodyMember(last).get_rigid_body():
95  apply_restraint = False
96 
97  if apply_restraint:
98 
99  nreslast = len(IMP.pmi.tools.get_residue_indexes(last))
100  lastresn = IMP.pmi.tools.get_residue_indexes(last)[-1]
101  nresfirst = len(IMP.pmi.tools.get_residue_indexes(first))
102  firstresn = IMP.pmi.tools.get_residue_indexes(first)[0]
103 
104  residuegap = firstresn - lastresn - 1
105  if disorderedlength and (nreslast / 2 + nresfirst / 2 + residuegap) > 20.0:
106  # calculate the distance between the sphere centers using Kohn
107  # PNAS 2004
108  optdist = sqrt(5 / 3) * 1.93 * \
109  (nreslast / 2 + nresfirst / 2 + residuegap) ** 0.6
110  # optdist2=sqrt(5/3)*1.93*((nreslast)**0.6+(nresfirst)**0.6)/2
111  if upperharmonic:
112  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
113  else:
114  hu = IMP.core.Harmonic(optdist, self.kappa)
116  else: # default
117  optdist = (0.0 + (float(residuegap) + 1.0) * 3.6) * scale
118  if upperharmonic: # default
119  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
120  else:
121  hu = IMP.core.Harmonic(optdist, self.kappa)
123 
124  pt0 = last.get_particle()
125  pt1 = first.get_particle()
126  r = IMP.core.PairRestraint(self.m, dps, (pt0.get_index(), pt1.get_index()))
127 
128  print("Adding sequence connectivity restraint between", pt0.get_name(), " and ", pt1.get_name(), 'of distance', optdist)
129  self.rs.add_restraint(r)
130 
131  def set_label(self, label):
132  self.label = label
133 
134  def get_weight(self):
135  return self.weight
136 
137  def add_to_model(self):
138  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
139 
140  def get_restraint(self):
141  return self.rs
142 
143  def set_weight(self, weight):
144  self.weight = weight
145  self.rs.set_weight(weight)
146 
147  def get_output(self):
148  self.m.update()
149  output = {}
150  score = self.weight * self.rs.unprotected_evaluate(None)
151  output["_TotalScore"] = str(score)
152  output["ConnectivityRestraint_" + self.label] = str(score)
153  return output
154 
156  """ Returns number of connectivity restraints """
157  return len(self.rs.get_restraints())
158 
159  def evaluate(self):
160  return self.weight * self.rs.unprotected_evaluate(None)
161 
162 class ExcludedVolumeSphere(object):
163  """A class to create an excluded volume restraint for a set of particles at a given resolution.
164  Can be initialized as a bipartite restraint between two sets of particles.
165  # Potential additional function: Variable resolution for each PMI object. Perhaps passing selection_tuples
166  with (PMI_object, resolution)
167  """
168 
169  def __init__(self,
170  representation=None,
171  included_objects=None,
172  other_objects=None,
173  resolution=1000,
174  kappa=1.0):
175  """Constructor.
176  @param representation DEPRECATED - just pass objects
177  @param included_objects Can be one of the following inputs:
178  IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set of them
179  @param other_objects Initializes a bipartite restraint between included_objects and other_objects
180  Same format as included_objects
181  @param resolution The resolution particles at which to impose the restraint.
182  By default, the coarsest particles will be chosen.
183  If a number is chosen, for each particle, the closest
184  resolution will be used (see IMP.atom.Selection).
185  @param kappa Restraint strength
186  """
187 
188  self.weight = 1.0
189  self.kappa = kappa
190  self.label = "None"
191  self.cpc = None
192  bipartite = False
193 
194  # gather IMP hierarchies from input objects
195  hierarchies = IMP.pmi.tools.input_adaptor(included_objects,
196  resolution,
197  flatten=True)
198  included_ps = []
199  if other_objects is not None:
200  bipartite = True
201  other_hierarchies = IMP.pmi.tools.input_adaptor(other_objects,
202  resolution,
203  flatten=True)
204  other_ps = []
205 
206 
207  # perform selection
208  if representation is None:
209  if hierarchies is None:
210  raise Exception("Must at least pass included objects")
211  self.mdl = hierarchies[0].get_model()
212  included_ps = [h.get_particle() for h in hierarchies]
213  if bipartite:
214  other_ps = [h.get_particle() for h in other_hierarchies]
215  elif isinstance(representation, IMP.pmi.representation.Representation):
216  self.mdl = representation.m
217  included_ps = IMP.pmi.tools.select(
218  representation,
219  resolution=resolution,
220  hierarchies=hierarchies)
221  if bipartite:
222  other_ps = IMP.pmi.tools.select(
223  representation,
224  resolution=resolution,
225  hierarchies=other_hierarchies)
226  else:
227  raise Exception("Must pass Representation or included_objects")
228 
229  # setup score
230  self.rs = IMP.RestraintSet(self.mdl, 'excluded_volume')
231  ssps = IMP.core.SoftSpherePairScore(self.kappa)
233  lsa.add(IMP.get_indexes(included_ps))
234 
235  # setup close pair container
236  if not bipartite:
238  self.cpc = IMP.container.ClosePairContainer(lsa, 0.0, rbcpf, 10.0)
239  evr = IMP.container.PairsRestraint(ssps, self.cpc)
240  else:
241  other_lsa = IMP.container.ListSingletonContainer(self.mdl)
242  other_lsa.add(IMP.get_indexes(other_ps))
244  lsa,
245  other_lsa,
246  0.0,
247  10.0)
248  evr = IMP.container.PairsRestraint(ssps, self.cpc)
249 
250  self.rs.add_restraint(evr)
251 
252  def add_excluded_particle_pairs(self, excluded_particle_pairs):
253  # add pairs to be filtered when calculating the score
254  lpc = IMP.container.ListPairContainer(self.mdl)
255  lpc.add(IMP.get_indexes(excluded_particle_pairs))
257  self.cpc.add_pair_filter(icpf)
258 
259  def set_label(self, label):
260  self.label = label
261 
262  def add_to_model(self):
263  IMP.pmi.tools.add_restraint_to_model(self.mdl, self.rs)
264 
265  def get_restraint(self):
266  return self.rs
267 
268  def set_weight(self, weight):
269  self.weight = weight
270  self.rs.set_weight(weight)
271 
272  def get_output(self):
273  self.mdl.update()
274  output = {}
275  score = self.weight * self.rs.unprotected_evaluate(None)
276  output["_TotalScore"] = str(score)
277  output["ExcludedVolumeSphere_" + self.label] = str(score)
278  return output
279 
280  def evaluate(self):
281  return self.weight * self.rs.unprotected_evaluate(None)
282 
283 class HelixRestraint(object):
284  """Enforce ideal Helix dihedrals and bonds for a selection at resolution 0"""
285  def __init__(self,
286  hierarchy,
287  selection_tuple,
288  weight=1.0,
289  label=''):
290  """Constructor
291  @param hierarchy the root node
292  @param selection_tuple (start, stop, molname, copynum=0)
293  @param weight
294  """
295  self.mdl = hierarchy.get_model()
296  self.rs = IMP.RestraintSet(self.mdl)
297  self.weight = weight
298  self.label = label
299  start = selection_tuple[0]
300  stop = selection_tuple[1]
301  mol = selection_tuple[2]
302  copy_index = 0
303  if len(selection_tuple)>3:
304  copy_index = selection_tuple[3]
305 
306  sel = IMP.atom.Selection(hierarchy,molecule=mol,copy_index=copy_index,
307  residue_indexes=range(start,stop+1))
308  ps = sel.get_selected_particles(with_representation=False)
309  res = [IMP.atom.Residue(p) for p in ps]
310  self.rs = IMP.RestraintSet(self.mdl,self.weight)
311  self.r = IMP.atom.HelixRestraint(res)
312  self.rs.add_restraint(self.r)
313  print('Created helix %s.%i.%i-%i with %i dihedrals and %i bonds'%(
314  mol,copy_index,start,stop,
315  self.get_number_of_bonds(),self.get_number_of_dihedrals()))
316  def set_label(self, label):
317  self.label = label
318 
319  def get_weight(self):
320  return self.weight
321 
322  def add_to_model(self):
323  IMP.pmi.tools.add_restraint_to_model(self.mdl, self.rs)
324 
325  def get_restraint(self):
326  return self.rs
327 
328  def set_weight(self, weight):
329  self.weight = weight
330  self.rs.set_weight(weight)
331 
332  def get_number_of_bonds(self):
333  return self.r.get_number_of_bonds()
334 
335  def get_number_of_dihedrals(self):
336  return self.r.get_number_of_dihedrals()
337 
338  def evaluate(self):
339  return self.weight * self.rs.unprotected_evaluate(None)
340 
341  def get_output(self):
342  self.mdl.update()
343  output = {}
344  score = self.evaluate()
345  output["_TotalScore"] = str(score)
346  output["HelixRestraint_" + self.label] = str(score)
347  return output
348 
349 class ResidueBondRestraint(object):
350  """ Add bond restraint between pair of consecutive
351  residues/beads to enforce the stereochemistry.
352  """
353  def __init__(self,
354  representation=None,
355  selection_tuple=None,
356  objects=None,
357  distance=3.78,
358  strength=10.0,
359  jitter=None):
360  """Constructor
361  @param representation (PMI1)
362  @param selection_tuple Requested selection (PMI1)
363  @param objects (PMI2)
364  @param distance Resting distance for restraint
365  @param strength Bond constant
366  @param jitter Defines the +- added to the optimal distance in the harmonic well restraint
367  used to increase the tolerance
368  """
369 
370  if representation is not None and selection_tuple is not None:
371  self.m = representation.prot.get_model()
372  particles = IMP.pmi.tools.select_by_tuple(
373  representation,
374  selection_tuple,
375  resolution=1)
376 
377  elif objects is not None:
378  particles = IMP.pmi.tools.input_adaptor(objects,1,flatten=True)
379  self.m = particles[0].get_model()
380 
381  self.rs = IMP.RestraintSet(self.m, "Bonds")
382  self.weight = 1
383  self.label = "None"
384  self.pairslist = []
385 
386 
387 
388  if not jitter:
389  ts = IMP.core.Harmonic(distance, strength)
390  else:
392  (distance - jitter, distance + jitter), strength)
393 
394  for ps in IMP.pmi.tools.sublist_iterator(particles, 2, 2):
395  pair = []
396  if len(ps) != 2:
397  raise ValueError("wrong length of pair")
398  for p in ps:
400  raise TypeError("not a residue")
401  else:
402  pair.append(p)
403  print("ResidueBondRestraint: adding a restraint between %s %s" % (pair[0].get_name(), pair[1].get_name()))
404  self.rs.add_restraint(
405  IMP.core.DistanceRestraint(self.m, ts, pair[0], pair[1]))
406  self.pairslist.append(IMP.ParticlePair(pair[0], pair[1]))
407  self.pairslist.append(IMP.ParticlePair(pair[1], pair[0]))
408 
409  def set_label(self, label):
410  self.label = label
411  self.rs.set_name(label)
412  for r in self.rs.get_restraints():
413  r.set_name(label)
414 
415  def add_to_model(self):
416  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
417 
418  def get_restraint(self):
419  return self.rs
420 
421  def set_weight(self, weight):
422  self.weight = weight
423  self.rs.set_weight(weight)
424 
425  def get_excluded_pairs(self):
426  return self.pairslist
427 
428  def get_output(self):
429  self.m.update()
430  output = {}
431  score = self.weight * self.rs.unprotected_evaluate(None)
432  output["_TotalScore"] = str(score)
433  output["ResidueBondRestraint_" + self.label] = str(score)
434  return output
435 
436 
437 class ResidueAngleRestraint(object):
438  """Add angular restraint between triplets of consecutive
439  residues/beads to enforce the stereochemistry.
440  """
441  def __init__(self,
442  representation=None,
443  selection_tuple=None,
444  objects=None,
445  anglemin=100.0,
446  anglemax=140.0,
447  strength=10.0):
448 
449  if representation is not None and selection_tuple is not None:
450  self.m = representation.prot.get_model()
451  particles = IMP.pmi.tools.select_by_tuple(
452  representation,
453  selection_tuple,
454  resolution=1)
455 
456  elif objects is not None:
457  particles = IMP.pmi.tools.input_adaptor(objects,1,flatten=True)
458  self.m = particles[0].get_model()
459 
460  self.rs = IMP.RestraintSet(self.m, "Angles")
461  self.weight = 1
462  self.label = "None"
463  self.pairslist = []
464 
466  (pi * anglemin / 180.0,
467  pi * anglemax / 180.0),
468  strength)
469 
470  for ps in IMP.pmi.tools.sublist_iterator(particles, 3, 3):
471  triplet = []
472  if len(ps) != 3:
473  raise ValueError("wrong length of triplet")
474  for p in ps:
476  raise TypeError("not a residue")
477  else:
478  triplet.append(p)
479  print("ResidueAngleRestraint: adding a restraint between %s %s %s" % (triplet[0].get_name(), triplet[1].get_name(), triplet[2].get_name()))
480  self.rs.add_restraint(
481  IMP.core.AngleRestraint(triplet[0].get_model(), ts,
482  triplet[0],
483  triplet[1],
484  triplet[2]))
485  self.pairslist.append(IMP.ParticlePair(triplet[0], triplet[2]))
486  self.pairslist.append(IMP.ParticlePair(triplet[2], triplet[0]))
487 
488  def set_label(self, label):
489  self.label = label
490  self.rs.set_name(label)
491  for r in self.rs.get_restraints():
492  r.set_name(label)
493 
494  def add_to_model(self):
495  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
496 
497  def get_restraint(self):
498  return self.rs
499 
500  def set_weight(self, weight):
501  self.weight = weight
502  self.rs.set_weight(weight)
503 
504  def get_excluded_pairs(self):
505  return self.pairslist
506 
507  def get_output(self):
508  self.m.update()
509  output = {}
510  score = self.weight * self.rs.unprotected_evaluate(None)
511  output["_TotalScore"] = str(score)
512  output["ResidueAngleRestraint_" + self.label] = str(score)
513  return output
514 
515 
517  """Add dihedral restraints between quadruplet of consecutive
518  residues/beads to enforce the stereochemistry.
519  Give as input a string of "C" and "T", meaning cys (0+-40) or trans (180+-40)
520  dihedral. The length of the string must be \#residue-3.
521  Without the string, the dihedral will be assumed trans.
522  """
523  def __init__(
524  self,
525  representation=None,
526  selection_tuple=None,
527  objects=None,
528  stringsequence=None,
529  strength=10.0):
530 
531  if representation is not None and selection_tuple is not None:
532  self.m = representation.prot.get_model()
533  particles = IMP.pmi.tools.select_by_tuple(
534  representation,
535  selection_tuple,
536  resolution=1)
537 
538  elif objects is not None:
539  particles = IMP.pmi.tools.input_adaptor(objects,1,flatten=True)
540  self.m = particles[0].get_model()
541 
542  self.rs = IMP.RestraintSet(self.m, "Angles")
543  self.weight = 1
544  self.label = "None"
545  self.pairslist = []
546 
547  if stringsequence is None:
548  stringsequence = "T" * (len(particles) - 3)
549 
550  for n, ps in enumerate(IMP.pmi.tools.sublist_iterator(particles, 4, 4)):
551  quadruplet = []
552  if len(ps) != 4:
553  raise ValueError("wrong length of quadruplet")
554  for p in ps:
556  raise TypeError("not a residue")
557  else:
558  quadruplet.append(p)
559  dihedraltype = stringsequence[n]
560  if dihedraltype == "C":
561  anglemin = -20.0
562  anglemax = 20.0
564  (pi * anglemin / 180.0,
565  pi * anglemax / 180.0),
566  strength)
567  print("ResidueDihedralRestraint: adding a CYS restraint between %s %s %s %s" % (quadruplet[0].get_name(), quadruplet[1].get_name(),
568  quadruplet[2].get_name(), quadruplet[3].get_name()))
569  if dihedraltype == "T":
570  anglemin = 180 - 70.0
571  anglemax = 180 + 70.0
573  (pi * anglemin / 180.0,
574  pi * anglemax / 180.0),
575  strength)
576  print("ResidueDihedralRestraint: adding a TRANS restraint between %s %s %s %s" % (quadruplet[0].get_name(), quadruplet[1].get_name(),
577  quadruplet[2].get_name(), quadruplet[3].get_name()))
578  self.rs.add_restraint(
579  IMP.core.DihedralRestraint(self.m,ts,
580  quadruplet[0],
581  quadruplet[1],
582  quadruplet[2],
583  quadruplet[3]))
584  self.pairslist.append(
585  IMP.ParticlePair(quadruplet[0], quadruplet[3]))
586  self.pairslist.append(
587  IMP.ParticlePair(quadruplet[3], quadruplet[0]))
588 
589  def set_label(self, label):
590  self.label = label
591  self.rs.set_name(label)
592  for r in self.rs.get_restraints():
593  r.set_name(label)
594 
595  def add_to_model(self):
596  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
597 
598  def get_restraint(self):
599  return self.rs
600 
601  def set_weight(self, weight):
602  self.weight = weight
603  self.rs.set_weight(weight)
604 
605  def get_excluded_pairs(self):
606  return self.pairslist
607 
608  def get_output(self):
609  self.m.update()
610  output = {}
611  score = self.weight * self.rs.unprotected_evaluate(None)
612  output["_TotalScore"] = str(score)
613  output["ResidueDihedralRestraint_" + self.label] = str(score)
614  return output
615 
616 class SecondaryStructure(object):
617  """Experimental, requires isd_emxl for now"""
618  def __init__(self,
619  representation,
620  selection_tuple,
621  ssstring,
622  mixture=False,
623  nativeness=1.0,
624  kt_caff=0.1):
625 
626  if no_isd_emxl:
627  raise ValueError("IMP.isd_emxl is needed")
628 
629  # check that the secondary structure string
630  # is compatible with the ssstring
631 
632  self.particles = IMP.pmi.tools.select_by_tuple(
633  representation,
634  selection_tuple,
635  resolution=1)
636  self.m = representation.prot.get_model()
637  self.dihe_dict = {}
638  self.ang_dict = {}
639  self.do_mix = {}
640  self.anglfilename = IMP.isd_emxl.get_data_path("CAAngleRestraint.dat")
641  self.dihefilename = IMP.isd_emxl.get_data_path(
642  "CADihedralRestraint.dat")
643  self.nativeness = nativeness
644  self.kt_caff = kt_caff
645  self.anglrs = IMP.RestraintSet(self.m, "Angles")
646  self.dihers = IMP.RestraintSet(self.m, "Dihedrals")
647  self.bondrs = IMP.RestraintSet(self.m, "Bonds")
648  self.label = "None"
649 
650  if len(self.particles) != len(ssstring):
651  print(len(self.particles), len(ssstring))
652  print("SecondaryStructure: residue range and SS string incompatible")
653  self.ssstring = ssstring
654 
655  (bondrslist, anglrslist, diherslist,
656  pairslist) = self.get_CA_force_field()
657  self.pairslist = pairslist
658 
659  # print anglrslist, diherslist, bondrslist, self.particles
660  self.anglrs.add_restraints(anglrslist)
661  self.dihers.add_restraints(diherslist)
662  self.bondrs.add_restraints(bondrslist)
663 
664  def set_label(self, label):
665  self.label = label
666 
667  def add_to_model(self):
668  IMP.pmi.tools.add_restraint_to_model(self.m, self.anglrs)
669  IMP.pmi.tools.add_restraint_to_model(self.m, self.dihers)
670  IMP.pmi.tools.add_restraint_to_model(self.m, self.bondrs)
671 
672  def get_CA_force_field(self):
673  bondrslist = []
674  anglrslist = []
675  diherslist = []
676  pairslist = []
677  # add bonds
678  for res in range(0, len(self.particles) - 1):
679 
680  ps = self.particles[res:res + 2]
681  pairslist.append(IMP.ParticlePair(ps[0], ps[1]))
682  pairslist.append(IMP.ParticlePair(ps[1], ps[0]))
683  br = self.get_distance_restraint(ps[0], ps[1], 3.78, 416.0)
684  br.set_name('Bond_restraint')
685  bondrslist.append(br)
686  # add dihedrals
687  for res in range(0, len(self.particles) - 4):
688 
689  # if res not in dihe_dict: continue
690  # get the appropriate parameters
691  # get the particles
692  ps = self.particles[res:res + 5]
693  [phi0,
694  phi1,
695  score_dih] = self.read_potential_dihedral(
696  self.ssstring[res:res + 4],
697  True)
698  pairslist.append(IMP.ParticlePair(ps[0], ps[3]))
699  pairslist.append(IMP.ParticlePair(ps[3], ps[0]))
700  pairslist.append(IMP.ParticlePair(ps[1], ps[4]))
701  pairslist.append(IMP.ParticlePair(ps[4], ps[1]))
702  dr = IMP.isd_emxl.CADihedralRestraint(
703  ps[0],
704  ps[1],
705  ps[2],
706  ps[3],
707  ps[4],
708  phi0,
709  phi1,
710  score_dih)
711  dr.set_name('Dihedral restraint')
712  diherslist.append(dr)
713  # add angles
714  for res in range(0, len(self.particles) - 2):
715  ps = self.particles[res:res + 3]
716  [psi, score_ang] = self.read_potential_angle(
717  self.ssstring[res:res + 2], True)
718  pairslist.append(IMP.ParticlePair(ps[0], ps[2]))
719  pairslist.append(IMP.ParticlePair(ps[2], ps[0]))
720  dr = IMP.isd_emxl.CAAngleRestraint(
721  ps[0],
722  ps[1],
723  ps[2],
724  psi,
725  score_ang)
726  dr.set_name('Angle restraint')
727  anglrslist.append(dr)
728  return (bondrslist, anglrslist, diherslist, pairslist)
729 
730  def read_potential_dihedral(self, string, mix=False):
731  # read potentials for dihedral
732  score_dih = []
733  phi0 = []
734  phi1 = []
735  for i in range(0, 36):
736  phi0.append(i * 10.0 / 180.0 * pi)
737  phi1.append(i * 10.0 / 180.0 * pi)
738  for j in range(0, 36):
739  score_dih.append(0.0)
740  # open file
741  if not mix:
742  f = open(self.dihefilename, 'r')
743  for line in f.readlines():
744  riga = (line.strip()).split()
745  if (len(riga) == 4 and riga[0] == string):
746  ii = int(float(riga[1]) / 10.0)
747  jj = int(float(riga[2]) / 10.0)
748  score_dih[ii * len(phi0) + jj] = - \
749  self.kt_caff * self.log(float(riga[3]))
750  f.close()
751  if mix:
752  # mix random coil and native secondary structure
753  counts = []
754  for i in range(0, 36):
755  for j in range(0, 36):
756  counts.append(1.0)
757  f = open(self.dihefilename, 'r')
758  for line in f.readlines():
759  riga = (line.strip()).split()
760  if (len(riga) == 4 and riga[0] == string):
761  ii = int(float(riga[1]) / 10.0)
762  jj = int(float(riga[2]) / 10.0)
763  counts[ii * len(phi0) + jj] += self.nativeness * \
764  float(riga[3])
765  if (len(riga) == 4 and riga[0] == "-----"):
766  ii = int(float(riga[1]) / 10.0)
767  jj = int(float(riga[2]) / 10.0)
768  counts[ii * len(phi0) + jj] += (1.0 - self.nativeness) * \
769  float(riga[3])
770  f.close()
771  for i in range(len(counts)):
772  score_dih[i] = -self.kt_caff * self.log(counts[i])
773  return [phi0, phi1, score_dih]
774 
775  def read_potential_angle(self, string, mix=False):
776  # read potentials for angles
777  score_ang = []
778  psi = []
779  for i in range(0, 180):
780  psi.append(i / 180.0 * pi)
781  score_ang.append(0.0)
782  # read file
783  if not mix:
784  f = open(self.anglfilename, 'r')
785  for line in f.readlines():
786  riga = (line.strip()).split()
787  if (len(riga) == 3 and riga[0] == string):
788  ii = int(riga[1])
789  score_ang[ii] = -self.kt_caff * self.log(float(riga[2]))
790  f.close()
791  if mix:
792  # mix random coil and native secondary structure
793  counts = []
794  for i in range(0, 180):
795  counts.append(1.0)
796 
797  f = open(self.anglfilename, 'r')
798  for line in f.readlines():
799  riga = (line.strip()).split()
800  if (len(riga) == 3 and riga[0] == string):
801  ii = int(riga[1])
802  counts[ii] += self.nativeness * float(riga[2])
803  if (len(riga) == 3 and riga[0] == "---"):
804  ii = int(riga[1])
805  counts[ii] += (1.0 - self.nativeness) * float(riga[2])
806  f.close()
807  for i in range(0, 180):
808  score_ang[i] = -self.kt_caff * self.log(counts[i])
809  return [psi, score_ang]
810 
811  def get_excluded_pairs(self):
812  return self.pairslist
813 
814  def get_restraint(self):
815  tmprs = IMP.RestraintSet(self.m, 'tmp')
816  tmprs.add_restraint(self.anglrs)
817  tmprs.add_restraint(self.dihers)
818  tmprs.add_restraint(self.bondrs)
819  return tmprs
820 
821  def get_distance_restraint(self, p0, p1, d0, kappa):
822  h = IMP.core.Harmonic(d0, kappa)
824  pr = IMP.core.PairRestraint(self.m, dps, IMP.ParticlePair(p0, p1))
825  return pr
826 
827  def get_output(self):
828  output = {}
829  self.m.update()
830  score_angle = self.anglrs.unprotected_evaluate(None)
831  score_dihers = self.dihers.unprotected_evaluate(None)
832  score_bondrs = self.bondrs.unprotected_evaluate(None)
833  output["_TotalScore"] = str(score_angle + score_dihers + score_bondrs)
834 
835  output["SecondaryStructure_Angles_" + self.label] = str(score_angle)
836  output["SecondaryStructure_Dihedrals_" +
837  self.label] = str(score_dihers)
838  output["SecondaryStructure_Bonds_" + self.label] = str(score_bondrs)
839  return output
840 
841 
843  """Add harmonic restraints between all pairs
844  """
845  def __init__(self,representation=None,
846  selection_tuples=None,
847  resolution=1,
848  strength=0.01,
849  dist_cutoff=10.0,
850  ca_only=True,
851  hierarchy=None):
852  """Constructor
853  @param representation Representation object
854  @param selection_tuples Selecting regions for the restraint [[start,stop,molname,copy_index=0],...]
855  @param resolution Resolution for applying restraint
856  @param strength Bond strength
857  @param dist_cutoff Cutoff for making restraints
858  @param ca_only Selects only CAlphas. Only matters if resolution=0.
859  @param hierarchy Root hierarchy to select from, use this instead of representation
860  """
861 
862  particles = []
863  if representation is None and hierarchy is not None:
864  self.m = hierarchy.get_model()
865  for st in selection_tuples:
866  copy_index=0
867  if len(st)>3:
868  copy_index=st[3]
869  if not ca_only:
870  sel = IMP.atom.Selection(hierarchy,molecule=st[2],residue_indexes=range(st[0],st[1]+1),
871  copy_index=copy_index)
872  else:
873  sel = IMP.atom.Selection(hierarchy,molecule=st[2],residue_indexes=range(st[0],st[1]+1),
874  copy_index=copy_index,
875  atom_type=IMP.atom.AtomType("CA"))
876  particles+=sel.get_selected_particles()
877  elif representation is not None and type(representation)==IMP.pmi.representation.Representation:
878  self.m = representation.mdl
879  for st in selection_tuples:
880  print('selecting with',st)
881  for p in IMP.pmi.tools.select_by_tuple(representation,st,resolution=resolution):
882  if (resolution==0 and ca_only and IMP.atom.Atom(p).get_atom_type()!=IMP.atom.AtomType("CA")):
883  continue
884  else:
885  particles.append(p.get_particle())
886  else:
887  raise Exception("must pass representation or hierarchy")
888 
889  self.weight = 1
890  self.label = "None"
891  self.pairslist = []
892 
893  # create score
894  self.rs = IMP.pmi.create_elastic_network(particles,dist_cutoff,strength)
895  for r in self.rs.get_restraints():
896  a1,a2 = r.get_inputs()
897  self.pairslist.append(IMP.ParticlePair(a1,a2))
898  self.pairslist.append(IMP.ParticlePair(a2,a1))
899  print('ElasticNetwork: created',self.rs.get_number_of_restraints(),'restraints')
900 
901  def set_label(self, label):
902  self.label = label
903  self.rs.set_name(label)
904  for r in self.rs.get_restraints():
905  r.set_name(label)
906 
907  def add_to_model(self):
908  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
909 
910  def get_restraint(self):
911  return self.rs
912 
913  def set_weight(self, weight):
914  self.weight = weight
915  self.rs.set_weight(weight)
916 
917  def get_excluded_pairs(self):
918  return self.pairslist
919 
920  def get_output(self):
921  self.m.update()
922  output = {}
923  score = self.weight * self.rs.unprotected_evaluate(None)
924  output["_TotalScore"] = str(score)
925  output["ElasticNetworkRestraint_" + self.label] = str(score)
926  return output
927 
928 
930  """ Enable CHARMM force field """
931  def __init__(self,
932  root=None,
933  ff_temp=300.0,
934  zone_ps=None,
935  zone_size=10.0,
936  enable_nonbonded=True,
937  enable_bonded=True,
938  zone_nonbonded=False,
939  representation=None):
940  """Setup the CHARMM restraint on a selection. Expecting atoms.
941  @param root The node at which to apply the restraint
942  @param ff_temp The temperature of the force field
943  @param zone_ps Create a zone around this set of particles
944  Automatically includes the entire residue (incl. backbone)
945  @param zone_size The size for looking for neighbor residues
946  @param enable_nonbonded Allow the repulsive restraint
947  @param enable_bonded Allow the bonded restraint
948  @param zone_nonbonded EXPERIMENTAL: exclude from nonbonded all sidechains that aren't in zone!
949  @param representation Legacy representation object
950  """
951 
952  kB = (1.381 * 6.02214) / 4184.0
953  if representation is not None:
954  root = representation.prot
955 
956  self.mdl = root.get_model()
957  self.bonds_rs = IMP.RestraintSet(self.mdl, 1.0 / (kB * ff_temp), 'BONDED')
958  self.nonbonded_rs = IMP.RestraintSet(self.mdl, 1.0 / (kB * ff_temp), 'NONBONDED')
959  self.weight = 1.0
960  self.label = ""
961 
962  ### setup topology and bonds etc
963  if enable_bonded:
965  topology = ff.create_topology(root)
966  topology.apply_default_patches()
967  topology.setup_hierarchy(root)
968  if zone_ps is not None:
969  limit_to_ps=IMP.pmi.topology.get_particles_within_zone(
970  root,
971  zone_ps,
972  zone_size,
973  entire_residues=True,
974  exclude_backbone=False)
976  topology,
977  limit_to_ps)
978  self.ps = limit_to_ps
979  else:
980  r = IMP.atom.CHARMMStereochemistryRestraint(root, topology)
981  self.ps = IMP.core.get_leaves(root)
982  print('init bonds score',r.unprotected_evaluate(None))
983  self.bonds_rs.add_restraint(r)
984  ff.add_radii(root)
985  ff.add_well_depths(root)
986 
987  atoms = IMP.atom.get_by_type(root,IMP.atom.ATOM_TYPE)
988  ### non-bonded forces
989  if enable_nonbonded:
990  if (zone_ps is not None) and zone_nonbonded:
991  print('stereochemistry: zone_nonbonded is True')
992  # atoms list should only include backbone plus zone_ps!
993  backbone_types=['C','N','CB','O']
994  sel = IMP.atom.Selection(root,atom_types=[IMP.atom.AtomType(n)
995  for n in backbone_types])
996  backbone_atoms = sel.get_selected_particles()
997  #x = list(set(backbone_atoms)|set(limit_to_ps))
998  sel_ps=IMP.pmi.topology.get_particles_within_zone(
999  root,
1000  zone_ps,
1001  zone_size,
1002  entire_residues=True,
1003  exclude_backbone=True)
1004 
1006  IMP.container.ListSingletonContainer(backbone_atoms),
1008  4.0)
1009  else:
1010  cont = IMP.container.ListSingletonContainer(self.mdl,atoms)
1011  self.nbl = IMP.container.ClosePairContainer(cont, 4.0)
1012  if enable_bonded:
1013  self.nbl.add_pair_filter(r.get_full_pair_filter())
1014  pairscore = IMP.isd.RepulsiveDistancePairScore(0,1)
1015  pr=IMP.container.PairsRestraint(pairscore, self.nbl)
1016  self.nonbonded_rs.add_restraint(pr)
1017  print('CHARMM is set up')
1018 
1019  def set_label(self, label):
1020  self.label = label
1021  self.rs.set_name(label)
1022  for r in self.rs.get_restraints():
1023  r.set_name(label)
1024 
1025  def add_to_model(self):
1026  IMP.pmi.tools.add_restraint_to_model(self.mdl, self.bonds_rs)
1027  IMP.pmi.tools.add_restraint_to_model(self.mdl, self.nonbonded_rs)
1028 
1029  def get_restraint(self):
1030  return self.rs
1031 
1032  def get_close_pair_container(self):
1033  return self.nbl
1034 
1035  def set_weight(self, weight):
1036  self.weight = weight
1037  self.rs.set_weight(weight)
1038 
1039  def get_output(self):
1040  self.mdl.update()
1041  output = {}
1042  bonds_score = self.weight * self.bonds_rs.unprotected_evaluate(None)
1043  nonbonded_score = self.weight * self.nonbonded_rs.unprotected_evaluate(None)
1044  score=bonds_score+nonbonded_score
1045  output["_TotalScore"] = str(score)
1046  output["CHARMM_BONDS"] = str(bonds_score)
1047  output["CHARMM_NONBONDED"] = str(nonbonded_score)
1048  return output
1049 
1050 
1052  """Add bonds and improper dihedral restraints for the CBs
1053  """
1054  def __init__(
1055  self, rnums, representation, selection_tuple, strength=10.0, kappa=1.0,
1056  jitter_angle=0.0, jitter_improper=0.0):
1057  '''
1058  need to add:
1059  ca-ca bond
1060  ca-cb is a constraint, no restraint needed
1061  ca-ca-ca
1062  cb-ca-ca-cb
1063  '''
1064 
1065  self.m = representation.prot.get_model()
1066  self.rs = IMP.RestraintSet(self.m, "PseudoAtomic")
1067  self.rset_angles = IMP.RestraintSet(self.m, "PseudoAtomic_Angles")
1068  self.rset_bonds = IMP.RestraintSet(self.m, "PseudoAtomic_Bonds")
1069  self.weight = 1
1070  self.label = "None"
1071  self.pairslist = []
1072 
1073  # residues=IMP.pmi.tools.select_by_tuple(representation,selection_tuple,resolution=1)
1074  for rnum in rnums:
1075  ca, cb = self.get_ca_cb(
1076  IMP.pmi.tools.select_by_tuple(representation,
1077  (rnum, rnum, 'chainA'), resolution=0))
1078  if not cb is None:
1079  nter = False
1080  cter = False
1081  ca_prev, cb_prev = self.get_ca_cb(
1082  IMP.pmi.tools.select_by_tuple(representation,
1083  (rnum - 1, rnum - 1, 'chainA'), resolution=0))
1084  ca_next, cb_next = self.get_ca_cb(
1085  IMP.pmi.tools.select_by_tuple(representation,
1086  (rnum + 1, rnum + 1, 'chainA'), resolution=0))
1087  if ca_prev is None:
1088  nter = True
1089  else:
1090  if ca_next is None:
1091  cter = True
1092  else:
1093  if (nter and cter):
1094  continue
1095 
1096  # adding a bond restraint between CA and CB
1097  # h=IMP.core.Harmonic(6.0,kappa)
1098  # dps=IMP.core.DistancePairScore(h)
1099  # pr=IMP.core.PairRestraint(dps,IMP.ParticlePair(ca,cb))
1100  # self.pairslist.append((ca,cb))
1101  # self.rset_bonds.add_restraint(pr)
1102 
1103  # creating improper dihedral restraint
1104  # hus=IMP.core.Harmonic(2.09,kappa)
1106  2.09 +
1107  jitter_angle /
1108  0.5,
1109  kappa)
1111  2.09 -
1112  jitter_angle /
1113  0.5,
1114  kappa)
1115  if not nter:
1116  # ar13=IMP.core.AngleRestraint(hus,ca_prev,ca,cb)
1117  # self.rset_angles.add_restraint(ar13)
1118  ar13u = IMP.core.AngleRestraint(hupp, ca_prev, ca, cb)
1119  ar13l = IMP.core.AngleRestraint(hlow, ca_prev, ca, cb)
1120  self.rset_angles.add_restraint(ar13u)
1121  self.rset_angles.add_restraint(ar13l)
1122  if not cter:
1123  # ar23=IMP.core.AngleRestraint(hus,ca_next,ca,cb)
1124  # self.rset_angles.add_restraint(ar23)
1125  ar23u = IMP.core.AngleRestraint(hupp, ca_next, ca, cb)
1126  ar23l = IMP.core.AngleRestraint(hlow, ca_next, ca, cb)
1127  self.rset_angles.add_restraint(ar23u)
1128  self.rset_angles.add_restraint(ar23l)
1129  if not nter and not cter:
1130  # hus2=IMP.core.Harmonic(0,kappa)
1131  # idr=IMP.core.DihedralRestraint(hus2,ca,ca_prev,ca_next,cb)
1132  # self.rset_angles.add_restraint(idr)
1133 
1134  hus2upp = IMP.core.HarmonicUpperBound(
1135  jitter_improper,
1136  kappa)
1137  hus2low = IMP.core.HarmonicLowerBound(
1138  -
1139  jitter_improper,
1140  kappa)
1142  hus2upp,
1143  ca,
1144  ca_prev,
1145  ca_next,
1146  cb)
1148  hus2low,
1149  ca,
1150  ca_prev,
1151  ca_next,
1152  cb)
1153  self.rset_angles.add_restraint(idru)
1154  self.rset_angles.add_restraint(idrl)
1155  self.rs.add_restraint(self.rset_bonds)
1156  self.rs.add_restraint(self.rset_angles)
1157 
1158  def get_ca_cb(self, atoms):
1159  ca = None
1160  cb = None
1161  for a in atoms:
1162  if IMP.atom.Atom(a).get_atom_type() == IMP.atom.AtomType("CA"):
1163  ca = a.get_particle()
1164  elif IMP.atom.Atom(a).get_atom_type() == IMP.atom.AtomType("CB"):
1165  cb = a.get_particle()
1166  return ca, cb
1167 
1168  def set_label(self, label):
1169  self.label = label
1170  self.rs.set_name(label)
1171  for r in self.rs.get_restraints():
1172  r.set_name(label)
1173 
1174  def add_to_model(self):
1175  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
1176 
1177  def get_restraint(self):
1178  return self.rs
1179 
1180  def set_weight(self, weight):
1181  self.weight = weight
1182  self.rs.set_weight(weight)
1183 
1184  def get_excluded_pairs(self):
1185  return self.pairslist
1186 
1187  def get_output(self):
1188  self.m.update()
1189  output = {}
1190  score = self.weight * self.rs.unprotected_evaluate(None)
1191  output["_TotalScore"] = str(score)
1192  output["PseudoAtomicRestraint_" + self.label] = str(score)
1193  return output
1194 
1195 class SymmetryRestraint(object):
1196  """Create harmonic restraints between the reference and (transformed) clones.
1197  \note Wraps IMP::core::TransformedDistancePairScore with an IMP::core::Harmonic
1198  """
1199  def __init__(self,
1200  references,
1201  clones_list,
1202  transforms,
1203  label='',
1204  strength=10.0):
1205  """Constructor
1206  @param references List of particles for symmetry reference
1207  @param clones_list List of lists of clone particles
1208  @param transforms Transforms moving each selection to the first selection
1209  @param label Label for output
1210  @param strength The elastic bond strength
1211  \note You will have to perform an IMP::atom::Selection to get the particles you need.
1212  Will check to make sure the numbers match.
1213  """
1214  self.mdl = root.get_model()
1215  self.rs = IMP.RestraintSet(self.mdl, "Symmetry")
1216  self.weight = 1
1217  self.label = label
1218  if len(clones_list)!=len(transforms):
1219  raise Exception('Error: There should be as many clones as transforms')
1220 
1221  harmonic = IMP.core.Harmonic(0.,strength)
1222  for clones,trans in zip(clones_list,transforms):
1223  if len(clones)!=len(references):
1224  raise Exception("Error: len(references)!=len(clones)")
1225  pair_score = IMP.core.TransformedDistancePairScore(harmonic,trans)
1226  for p0,p1 in zip(references,clones):
1227  r = IMP.core.PairRestraint(pair_score,(p0,p1))
1228  self.rs.add_restraint(r)
1229 
1230  print('created symmetry network with',self.rs.get_number_of_restraints(),'restraints')
1231 
1232  def set_label(self, label):
1233  self.label = label
1234  self.rs.set_name(label)
1235  for r in self.rs.get_restraints():
1236  r.set_name(label)
1237 
1238  def add_to_model(self):
1239  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
1240 
1241  def get_restraint(self):
1242  return self.rs
1243 
1244  def set_weight(self, weight):
1245  self.weight = weight
1246  self.rs.set_weight(weight)
1247 
1248  def get_excluded_pairs(self):
1249  return self.pairslist
1250 
1251  def get_output(self):
1252  self.mdl.update()
1253  output = {}
1254  score = self.weight * self.rs.unprotected_evaluate(None)
1255  output["SymmetryRestraint_" + self.label] = str(score)
1256  output["_TotalScore"] = str(score)
1257  return output
1258 
1259 
1260 class FusionRestraint(object):
1261  """ This class creates a restraint between the termini two polypeptides, to simulate the sequence connectivity. """
1262  def __init__(self,
1263  nterminal,
1264  cterminal,
1265  scale=1.0,
1266  disorderedlength=False,
1267  upperharmonic=True,
1268  resolution=1,
1269  label="None"):
1270  """
1271  @param nterminal - single PMI2 Hierarchy/molecule at the nterminal
1272  @param cterminal - single PMI2 Hierarchy/molecule at the cterminal
1273  @param scale Scale the maximal distance between the beads by this factor when disorderedlength is False.
1274  The maximal distance is calculated as ((float(residuegap) + 1.0) * 3.6) * scale.
1275  @param disorderedlength - This flag uses either disordered length
1276  calculated for random coil peptides (True) or zero
1277  surface-to-surface distance between beads (False)
1278  as optimal distance for the sequence connectivity
1279  restraint.
1280  @param upperharmonic - This flag uses either harmonic (False)
1281  or upperharmonic (True) in the intra-pair
1282  connectivity restraint.
1283  @param resolution - The resolution to connect things at - only used if you pass PMI objects
1284  @param label - A string to identify this restraint in the output/stat file
1285  """
1286  self.label = label
1287  self.weight = 1.0
1288  ssn=IMP.pmi.tools.get_sorted_segments(nterminal)
1289  ssc=IMP.pmi.tools.get_sorted_segments(cterminal)
1290  nter_lastres=ssn[-1][1]
1291  cter_firstres=ssc[0][0]
1292  self.m = nter_lastres.get_model()
1293 
1294  self.kappa = 10 # spring constant used for the harmonic restraints
1295 
1296  optdist = (3.6) * scale
1297  if upperharmonic: # default
1298  hu = IMP.core.HarmonicUpperBound(optdist, self.kappa)
1299  else:
1300  hu = IMP.core.Harmonic(optdist, self.kappa)
1302 
1303  pt0 = nter_lastres.get_particle()
1304  pt1 = cter_firstres.get_particle()
1305  r = IMP.core.PairRestraint(self.m, dps, (pt0.get_index(), pt1.get_index()))
1306  self.rs = IMP.RestraintSet(self.m, "fusion_restraint")
1307  print("Adding fusion connectivity restraint between", pt0.get_name(), " and ", pt1.get_name(), 'of distance', optdist)
1308  self.rs.add_restraint(r)
1309 
1310  def set_label(self, label):
1311  self.label = label
1312 
1313  def get_weight(self):
1314  return self.weight
1315 
1316  def add_to_model(self):
1317  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
1318 
1319  def get_restraint(self):
1320  return self.rs
1321 
1322  def set_weight(self, weight):
1323  self.weight = weight
1324  self.rs.set_weight(weight)
1325 
1326  def get_output(self):
1327  self.m.update()
1328  output = {}
1329  score = self.weight * self.rs.unprotected_evaluate(None)
1330  output["_TotalScore"] = str(score)
1331  output["FusionRestraint_" + self.label] = str(score)
1332  return output
1333 
1334  def evaluate(self):
1335  return self.weight * self.rs.unprotected_evaluate(None)
1336 
1337 
1338 
1339 
1341 
1342  """Restrain the dihedral between planes defined by three particles.
1343 
1344  This restraint is useful for restraining the twist of a string of
1345  more or less identical rigid bodies, so long as the curvature is mild.
1346  """
1347 
1348  def __init__(self, particle_triplets, angle=0., k=1., label=None,
1349  weight=1.):
1350  """Constructor
1351  @param particle_triplets List of lists of 3 particles. Each triplet
1352  defines a plane. Dihedrals of adjacent planes
1353  in list are scored.
1354  @param angle Angle of plane dihedral in degrees
1355  @param k Strength of restraint
1356  @param label Label for output
1357  @param weight Weight of restraint
1358  \note Particles defining planes should be rigid and more or less
1359  parallel for proper behavior
1360  """
1361  m = particle_triplets[0][0].get_model()
1362  super(PlaneDihedralRestraint, self).__init__(m, label=label,
1363  weight=weight)
1364 
1365  angle = pi * angle / 180.
1366  ds = IMP.core.Cosine(.5 * k, 1., -angle)
1367  for i, t1 in enumerate(particle_triplets[:-1]):
1368  t2 = particle_triplets[i + 1]
1369  q1 = [t1[1], t1[0], t2[0], t2[1]]
1370  q2 = [t1[2], t1[0], t2[0], t2[2]]
1371  self.rs.add_restraint(IMP.core.DihedralRestraint(self.m, ds, *q1))
1372  self.rs.add_restraint(IMP.core.DihedralRestraint(self.m, ds, *q2))
A filter which returns true if a container containers the Pair.
Add dihedral restraints between quadruplet of consecutive residues/beads to enforce the stereochemist...
CHARMMParameters * get_heavy_atom_CHARMM_parameters()
Lower bound harmonic function (non-zero when feature < mean)
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Residue.h:155
Enforce CHARMM stereochemistry on the given Hierarchy.
A member of a rigid body, it has internal (local) coordinates.
Definition: rigid_bodies.h:508
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:509
Various classes to hold sets of particles.
Upper bound harmonic function (non-zero when feature > mean)
A class to store an fixed array of same-typed values.
Definition: Array.h:33
Enforce ideal Helix dihedrals and bonds for a selection at resolution 0.
Miscellaneous utilities.
Definition: tools.py:1
Cosine function.
Definition: Cosine.h:22
This class creates a restraint between the termini two polypeptides, to simulate the sequence connect...
Add harmonic restraints between all pairs.
Apply a function to the distance between two particles after transforming the first.
Restrain the dihedral between planes defined by three particles.
Dihedral restraint between four particles.
The type of an atom.
A score on the distance between the surfaces of two spheres.
Return all close unordered pairs of particles taken from the SingletonContainer.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:619
Return all spatially-proximals pairs of particles (a,b) from the two SingletonContainers A and B...
GenericHierarchies get_leaves(Hierarchy mhd)
Get all the leaves of the bit of hierarchy.
Distance restraint between two particles.
Representation of the system.
Object used to hold a set of restraints.
Definition: RestraintSet.h:36
def input_adaptor
Adapt things for PMI (degrees of freedom, restraints, ...) Returns list of list of hierarchies...
Definition: tools.py:1608
Store a list of ParticleIndexPairs.
A well with harmonic barriers.
Definition: HarmonicWell.h:25
Angle restraint between three particles.
ParticleIndexPairs get_indexes(const ParticlePairsTemp &ps)
Add bond restraint between pair of consecutive residues/beads to enforce the stereochemistry.
The standard decorator for manipulating molecular structures.
RestraintSet * create_elastic_network(const Particles &ps, Float dist_cutoff, Float strength)
Create an elastic network restraint set.
Definition: utilities.h:26
Add bonds and improper dihedral restraints for the CBs.
Store a list of ParticleIndexes.
A decorator for a particle representing an atom.
Definition: atom/Atom.h:234
def add_restraint_to_model
Add a PMI restraint to the model.
Definition: tools.py:37
def __init__
Setup the CHARMM restraint on a selection.
Create harmonic restraints between the reference and (transformed) clones.
Add angular restraint between triplets of consecutive residues/beads to enforce the stereochemistry...
def get_num_restraints
Returns number of connectivity restraints.
A decorator for a residue.
Definition: Residue.h:134
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...
This class creates a restraint between consecutive TempResidue objects OR an entire PMI MOlecule obje...
A class to create an excluded volume restraint for a set of particles at a given resolution.
The general base class for IMP exceptions.
Definition: exception.h:49
def __init__
need to add: ca-ca bond ca-cb is a constraint, no restraint needed ca-ca-ca cb-ca-ca-cb ...
Applies a PairScore to a Pair.
Definition: PairRestraint.h:29
def select
this function uses representation=SimplifiedModel it returns the corresponding selected particles rep...
Definition: tools.py:731
Experimental, requires isd_emxl for now.
Set up the representation of all proteins and nucleic acid macromolecules.
def get_sorted_segments
Returns sequence-sorted segments array, each containing the first particle the last particle and the ...
Definition: tools.py:1723
Functionality for loading, creating, manipulating and scoring atomic structures.
Select hierarchy particles identified by the biological name.
Definition: Selection.h:66
Applies a PairScore to each Pair in a list.
def get_residue_indexes
Retrieve the residue indexes for the given particle.
Definition: tools.py:1068
A repulsive potential on the distance between two atoms.
Perform more efficient close pair finding when rigid bodies are involved.
Base class for PMI restraints, which wrap IMP.Restraint(s).
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...
def sublist_iterator
Yield all sublists of length >= lmin and <= lmax.
Definition: tools.py:1164
Harmonic function (symmetric about the mean)
Definition: core/Harmonic.h:24
Restraint a set of residues to use ideal helix dihedrals and bonds.