IMP logo
IMP Reference Guide  2.12.0
The Integrative Modeling Platform
restraints/basic.py
1 """@namespace IMP.pmi.restraints.basic
2 Some miscellaneous simple restraints.
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.pmi.tools
12 import IMP.pmi.restraints
13 
14 
16 
17  """Restraint to keep all structures inside sphere."""
18 
19  def __init__(self,
20  representation=None,
21  radius=10.0,
22  hierarchies=None,
23  resolution=10,
24  weight=1.0,
25  center=None,
26  label=None):
27  """Setup external barrier restraint.
28  @param representation DEPRECATED
29  @param radius Size of external barrier
30  @param hierarchies Can be one of the following inputs: IMP Hierarchy,
31  PMI System/State/Molecule/TempResidue, or a list/set of them
32  @param resolution Select which resolutions to act upon
33  @param weight Weight of restraint
34  @param center Center of the external barrier restraint
35  (IMP.algebra.Vector3D object)
36  @param label A unique label to be used in outputs and
37  particle/restraint names.
38  """
39  if representation:
40  model = representation.prot.get_model()
41  particles = IMP.pmi.tools.select(
42  representation,
43  resolution=resolution,
44  hierarchies=hierarchies)
45  elif hierarchies:
46  hiers = IMP.pmi.tools.input_adaptor(hierarchies, resolution,
47  flatten=True)
48  model = hiers[0].get_model()
49  particles = [h.get_particle() for h in hiers]
50  else:
51  raise Exception("%s: must pass representation or hierarchies" % (
52  self.name))
53 
54  super(ExternalBarrier, self).__init__(model, label=label,
55  weight=weight)
56  self.radius = radius
57 
58  if center is None:
59  c3 = IMP.algebra.Vector3D(0, 0, 0)
60  elif type(center) is IMP.algebra.Vector3D:
61  c3 = center
62  else:
63  raise Exception(
64  "%s: @param center must be an IMP.algebra.Vector3D object" % (
65  self.name))
66 
67  ub3 = IMP.core.HarmonicUpperBound(radius, 10.0)
69  lsc = IMP.container.ListSingletonContainer(self.model)
70 
71  lsc.add(particles)
73  self.rs.add_restraint(r3)
74 
75 
77 
78  """A simple distance restraint"""
79 
80  def __init__(self,
81  representation=None,
82  tuple_selection1=None,
83  tuple_selection2=None,
84  distancemin=0,
85  distancemax=100,
86  resolution=1.0,
87  kappa=1.0,
88  root_hier=None,
89  label=None,
90  weight=1.):
91  """Setup distance restraint.
92  @param representation DEPRECATED
93  @param tuple_selection1 (resnum, resnum, molecule name, copy
94  number (=0))
95  @param tuple_selection2 (resnum, resnum, molecule name, copy
96  number (=0))
97  @param distancemin The minimum dist
98  @param distancemax The maximum dist
99  @param resolution For selecting particles
100  @param kappa The harmonic parameter
101  @param root_hier The hierarchy to select from (use this instead of
102  representation)
103  @param label A unique label to be used in outputs and
104  particle/restraint names
105  @param weight Weight of restraint
106  @note Pass the same resnum twice to each tuple_selection. Optionally
107  add a copy number (PMI2 only)
108  """
109  if tuple_selection1 is None or tuple_selection2 is None:
110  raise Exception("You must pass tuple_selection1/2")
111  ts1 = IMP.core.HarmonicUpperBound(distancemax, kappa)
112  ts2 = IMP.core.HarmonicLowerBound(distancemin, kappa)
113 
114  if representation and not root_hier:
115  model = representation.prot.get_model()
116  particles1 = IMP.pmi.tools.select(representation,
117  resolution=resolution,
118  name=tuple_selection1[2],
119  residue=tuple_selection1[0])
120  particles2 = IMP.pmi.tools.select(representation,
121  resolution=resolution,
122  name=tuple_selection2[2],
123  residue=tuple_selection2[0])
124  elif root_hier and not representation:
125  model = root_hier.get_model()
126  copy_num1 = 0
127  if len(tuple_selection1) > 3:
128  copy_num1 = tuple_selection1[3]
129  copy_num2 = 0
130  if len(tuple_selection2) > 3:
131  copy_num2 = tuple_selection2[3]
132 
133  sel1 = IMP.atom.Selection(root_hier,
134  resolution=resolution,
135  molecule=tuple_selection1[2],
136  residue_index=tuple_selection1[0],
137  copy_index=copy_num1)
138  particles1 = sel1.get_selected_particles()
139  sel2 = IMP.atom.Selection(root_hier,
140  resolution=resolution,
141  molecule=tuple_selection2[2],
142  residue_index=tuple_selection2[0],
143  copy_index=copy_num2)
144  particles2 = sel2.get_selected_particles()
145  else:
146  raise Exception("Pass representation or root_hier, not both")
147 
148  super(DistanceRestraint, self).__init__(model, label=label,
149  weight=weight)
150  print(self.name)
151 
152  print("Created distance restraint between "
153  "%s and %s" % (particles1[0].get_name(),
154  particles2[0].get_name()))
155 
156  if len(particles1) > 1 or len(particles2) > 1:
157  raise ValueError("more than one particle selected")
158 
159  self.rs.add_restraint(
160  IMP.core.DistanceRestraint(self.model, ts1,
161  particles1[0],
162  particles2[0]))
163  self.rs.add_restraint(
164  IMP.core.DistanceRestraint(self.model, ts2,
165  particles1[0],
166  particles2[0]))
167 
168 
170  '''
171  PMI2 python restraint. Restrains particles within a
172  Cylinder aligned along the z-axis and
173  centered in x,y=0,0
174  Optionally, one can restrain the cylindrical angle
175  '''
176  import math
177  def __init__(self, m, objects, resolution, radius,mintheta=None,
178  maxtheta=None,repulsive=False,label='None'):
179  '''
180  @param objects PMI2 objects
181  @param resolution the resolution you want the restraint to be applied
182  @param radius the radius of the cylinder
183  @param mintheta minimum cylindrical angle in degrees
184  @param maxtheta maximum cylindrical angle in degrees
185  '''
186  IMP.Restraint.__init__(self, m, "CylinderRestraint %1%")
187  self.radius=radius
188  self.softness = 3.0
189  self.softness_angle = 0.5
190  self.plateau = 1e-10
191  self.weight = 1.0
192  self.m=m
193  self.mintheta=mintheta
194  self.maxtheta=maxtheta
195  self.repulsive=repulsive
196  hierarchies = IMP.pmi.tools.input_adaptor(objects,
197  resolution,
198  flatten=True)
199  self.particles = [h.get_particle() for h in hierarchies]
200  self.label=label
201 
202  def get_probability(self,p):
203  xyz=IMP.core.XYZ(p)
204  r=self.math.sqrt(xyz.get_x()**2+xyz.get_y()**2)
205  argvalue=(r-self.radius) / self.softness
206  if self.repulsive: argvalue=-argvalue
207  prob = (1.0 - self.plateau) / (1.0 + self.math.exp(-argvalue))
208  return prob
209 
210  def get_angle_probability(self,p):
211  xyz=IMP.core.XYZ(p)
212  angle=self.math.atan2(xyz.get_y(),xyz.get_x() )*180.0/self.math.pi
213  anglediff = (angle - self.maxtheta + 180 + 360) % 360 - 180
214  argvalue1=anglediff / self.softness_angle
215  anglediff = (angle - self.mintheta + 180 + 360) % 360 - 180
216  argvalue2=-anglediff / self.softness_angle
217  prob = (1.0-self.plateau) / (1.0 + self.math.exp(-max(argvalue1,argvalue2)))
218  return prob
219 
220  def unprotected_evaluate(self, da):
221  s=0.0
222  for p in self.particles:
223  s+=-self.math.log(1.0-self.get_probability(p))
224  if self.mintheta is not None and self.maxtheta is not None:
225  s+=-self.math.log(1.0-self.get_angle_probability(p))
226  return s
227 
228  def do_get_inputs(self):
229  return self.particles
230 
231  def add_to_model(self):
233 
234  def get_output(self):
235  output = {}
236  score = self.weight * self.unprotected_evaluate(None)
237  output["_TotalScore"] = str(score)
238  output["CylinderRestraint_" + self.label] = str(score)
239  return output
240 
241 
242 
244  '''
245  a python restraint with bistable potential
246  Authors: G. Bouvier, R. Pellarin. Pasteur Institute.
247  '''
248  import numpy as np
249  import math
250 
251  def __init__(self,m,p1,p2,dist1,dist2,sigma1,sigma2,weight1,weight2):
252  '''
253  input twp particles, the two equilibrium distances, their amplitudes, and their weights (populations)
254  '''
255  IMP.Restraint.__init__(self, m, "BiStableDistanceRestraint %1%")
256  self.dist1=dist1
257  self.dist2=dist2
258 
259  self.sigma1=sigma1
260  self.sigma2=sigma2
261 
262  self.weight1=weight1
263  self.weight2=weight2
264 
265  if self.weight1+self.weight2 != 1:
266  raise ValueError("The sum of the weights must be one")
267 
268  self.d1=IMP.core.XYZ(p1)
269  self.d2=IMP.core.XYZ(p2)
270  self.particle_list=[p1,p2]
271 
272  def gaussian(self,x, mu, sig, w):
273  return w*self.np.exp(-self.np.power(x - mu, 2.) / (2 * self.np.power(sig, 2.)))
274 
275  def unprotected_evaluate(self,da):
276  dist=IMP.core.get_distance(self.d1,self.d2)
277  prob=self.gaussian(dist,self.dist1,self.sigma1,self.weight1)+\
278  self.gaussian(dist,self.dist2,self.sigma2,self.weight2)
279  return -self.math.log(prob)
280 
281  def do_get_inputs(self):
282  return self.particle_list
283 
284 
286 
287  """Restraint for anchoring a particle to a specific coordinate."""
288 
289  def __init__(self,
290  representation=None,
291  tuple_selection=None,
292  anchor_point=IMP.algebra.Vector3D(0, 0, 0),
293  radius=10.0,
294  kappa=10.0,
295  resolution=1.0,
296  weight=1.0,
297  root_hier=None,
298  label=None):
299  """Setup distance restraint.
300  @param representation DEPRECATED
301  @param tuple_selection (resnum, resnum, molecule name,
302  copy number (=0))
303  @param anchor_point Point to which to restrain particle
304  (IMP.algebra.Vector3D object)
305  @param radius Size of the tolerance length
306  @param kappa The harmonic parameter
307  @param resolution For selecting a particle
308  @param weight Weight of restraint
309  @param root_hier The hierarchy to select from (use this instead of
310  representation)
311  @param label A unique label to be used in outputs and
312  particle/restraint names
313  @note Pass the same resnum twice to each tuple_selection. Optionally
314  add a copy number (PMI2 only)
315  """
316  if tuple_selection is None:
317  raise ValueError("You must pass a tuple_selection")
318 
319  if representation and not root_hier:
320  model = representation.prot.get_model()
321  ps = IMP.pmi.tools.select(representation,
322  resolution=resolution,
323  name=tuple_selection[2],
324  residue=tuple_selection[0])
325  elif root_hier and not representation:
326  model = root_hier.get_model()
327  copy_num1 = 0
328  if len(tuple_selection) > 3:
329  copy_num1 = tuple_selection[3]
330 
331  sel1 = IMP.atom.Selection(root_hier,
332  resolution=resolution,
333  molecule=tuple_selection[2],
334  residue_index=tuple_selection[0],
335  copy_index=copy_num1)
336  ps = sel1.get_selected_particles()
337  else:
338  raise ValueError("Pass representation or root_hier, not both")
339  if len(ps) > 1:
340  raise ValueError("More than one particle selected")
341 
342  super(DistanceToPointRestraint, self).__init__(model, label=label,
343  weight=weight)
344  self.radius = radius
345 
346  ub3 = IMP.core.HarmonicUpperBound(self.radius, kappa)
347  if anchor_point is None:
348  c3 = IMP.algebra.Vector3D(0, 0, 0)
349  elif isinstance(anchor_point, IMP.algebra.Vector3D):
350  c3 = anchor_point
351  else:
352  raise TypeError("anchor_point must be an algebra.Vector3D object")
353  ss3 = IMP.core.DistanceToSingletonScore(ub3, c3)
354 
355  lsc = IMP.container.ListSingletonContainer(self.model)
356  lsc.add(ps)
357 
358  r3 = IMP.container.SingletonsRestraint(ss3, lsc)
359  self.rs.add_restraint(r3)
360 
361  print("\n%s: Created distance_to_point_restraint between "
362  "%s and %s" % (self.name, ps[0].get_name(), c3))
363 
365  def __init__(self,
366  hier,
367  objects_above=None,
368  objects_inside=None,
369  objects_below=None,
370  center = 0.0,
371  thickness=30.0,
372  softness=3.0,
373  plateau=0.0000000001,
374  resolution=1,
375  weight = 1.0,
376  label = None):
377  """ Setup Membrane restraint
378 
379  Simple sigmoid score calculated for particles above,
380 
381  @param objects_inside list or tuples of objects in membrane (e.g. ['p1', (10, 30,'p2')])
382  @param objects_above list or tuples of objects above membrane
383  @param objects_below list or tuples of objects below membrane
384  @param thickness Thickness of the membrane along the z-axis
385  @param softness Softness of the limiter in the sigmoid function
386  @param plateau Parameter to set the probability (=1- plateau)) at the plateau
387  phase of the sigmoid
388  @param weight Weight of restraint
389  @param label A unique label to be used in outputs and
390  particle/restraint names.
391  input a list of particles, the slope and theta of the sigmoid potential
392  theta is the cutoff distance for a protein-protein contact
393  """
394 
395  self.hier = hier
396  model = self.hier.get_model()
397 
398  rname = "MembraneRestraint"
399  super(MembraneRestraint, self).__init__(
400  model, name="MembraneRestraint", label=label, weight=weight)
401 
402  self.center = center
403  self.thickness = thickness
404  self.softness = softness
405  self.plateau = plateau
406  self.linear = 0.02
407  self.resolution = resolution
408 
409  # Create nuisance particle
410  p = IMP.Particle(model)
411  z_center = IMP.isd.Nuisance.setup_particle(p)
412  z_center.set_nuisance(self.center)
413 
414  # Setup restraint
415  mr = IMP.pmi.MembraneRestraint(model,
416  z_center.get_particle_index(),
417  self.thickness,
418  self.softness,
419  self.plateau,
420  self.linear)
421 
422  # Particles above
423  if objects_above:
424  for obj in objects_above:
425  if isinstance(obj, tuple):
426  self.particles_above = self._select_from_tuple(obj)
427 
428  elif isinstance(obj, str):
429  self.particles_above = self._select_from_string(obj)
430  mr.add_particles_above(self.particles_above)
431 
432  # Particles inside
433  if objects_inside:
434  for obj in objects_inside:
435  if isinstance(obj, tuple):
436  self.particles_inside = self._select_from_tuple(obj)
437 
438  elif isinstance(obj, str):
439  self.particles_inside = self._select_from_string(obj)
440  mr.add_particles_inside(self.particles_inside)
441 
442 
443  # Particles below
444  if objects_below:
445  for obj in objects_below:
446  if isinstance(obj, tuple):
447  self.particles_below = self._select_from_tuple(obj)
448 
449  elif isinstance(obj, str):
450  self.particles_below = self._select_from_string(obj)
451  mr.add_particles_below(self.particles_below)
452 
453 
454  self.rs.add_restraint(mr)
455 
456  def get_particles_above(self):
457  return self.particles_above
458 
459  def get_particles_inside(self):
460  return self.particles_inside
461 
462  def get_particles_below(self):
463  return self.particles_below
464 
465  def _select_from_tuple(self, obj):
466  particles = IMP.atom.Selection(self.hier,
467  molecule = obj[2],
468  residue_indexes = range(obj[0], obj[1]+1, 1),
469  resolution = self.resolution).get_selected_particles()
470 
471  return particles
472 
473  def _select_from_string(self, obj):
474  particles = IMP.atom.Selection(self.hier,
475  molecule = obj,
476  resolution = self.resolution).get_selected_particles()
477  return particles
478 
479  def create_membrane_density(self, file_out='membrane_localization.mrc'):
480 
481  '''
482  Just for visualization purposes.
483  Writes density of membrane localization
484  '''
485 
486  offset = 5.0*self.thickness
487  apix = 3.0
488  resolution = 5.0
489 
490  # Create a density header of the requested size
492  IMP.algebra.Vector3D(-self.center - offset, -self.center - offset, -self.center - offset,),
493  IMP.algebra.Vector3D(self.center + offset, self.center + offset, self.center + offset))
494  dheader = IMP.em.create_density_header(bbox, apix)
495  dheader.set_resolution(resolution)
496  dmap = IMP.em.SampledDensityMap(dheader)
497 
498  for vox in range(dmap.get_header().get_number_of_voxels()):
499  c = dmap.get_location_by_voxel(vox)
500  if self._is_membrane(c[2])==1:
501  dmap.set_value(c[0], c[1], c[2], 1.0)
502  else:
503  dmap.set_value(c[0], c[1], c[2], 0.0)
504 
505  IMP.em.write_map(dmap, file_out)
506 
507  def _is_membrane(self, z):
508  if (z-self.center) < self.thickness/2.0 and (z-self.center) >= -self.thickness/2.0 :
509  return 1
510  else:
511  return 0
Applies a SingletonScore to each Singleton in a list.
static Nuisance setup_particle(Model *m, ParticleIndex pi)
Definition: Nuisance.h:31
def __init__
Setup distance restraint.
Lower bound harmonic function (non-zero when feature < mean)
Various classes to hold sets of particles.
Upper bound harmonic function (non-zero when feature > mean)
Miscellaneous utilities.
Definition: tools.py:1
Distance restraint between two particles.
double get_distance(XYZR a, XYZR b)
Compute the sphere distance between a and b.
Definition: XYZR.h:89
Classes to handle different kinds of restraints.
def input_adaptor
Adapt things for PMI (degrees of freedom, restraints, ...) Returns list of list of hierarchies...
Definition: tools.py:918
def __init__
input twp particles, the two equilibrium distances, their amplitudes, and their weights (populations)...
Class for sampling a density map from particles.
def __init__
Setup external barrier restraint.
Store a list of ParticleIndexes.
Restraint for anchoring a particle to a specific coordinate.
def add_restraint_to_model
Add a PMI restraint to the model.
Definition: tools.py:89
DensityHeader create_density_header(const algebra::BoundingBoxD< 3 > &bb, float spacing)
Create a header from a bounding box in 3D.
Apply a function to the distance to a fixed point.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
Restraint to keep all structures inside sphere.
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...
The general base class for IMP exceptions.
Definition: exception.h:49
VectorD< 3 > Vector3D
Definition: VectorD.h:421
Class to handle individual particles of a Model object.
Definition: Particle.h:41
Functionality for loading, creating, manipulating and scoring atomic structures.
a python restraint with bistable potential Authors: G.
Select hierarchy particles identified by the biological name.
Definition: Selection.h:66
virtual ModelObjectsTemp do_get_inputs() const =0
Base class for PMI restraints, which wrap IMP.Restraint(s).
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:54