1 """@namespace IMP.pmi.restraints.basic
2 Some miscellaneous simple restraints.
16 """Keeps all structures inside a sphere."""
18 def __init__(self, hierarchies, radius=10.0, resolution=10, weight=1.0,
19 center=
None, label=
None):
20 """Setup external barrier restraint.
21 @param hierarchies Can be one of the following inputs: IMP Hierarchy,
22 PMI System/State/Molecule/TempResidue, or a list/set of them
23 @param radius Size of external barrier
24 @param resolution Select which resolutions to act upon
25 @param weight Weight of restraint
26 @param center Center of the external barrier
27 (IMP.algebra.Vector3D object)
28 @param label A unique label to be used in outputs and
29 particle/restraint names.
33 model = hiers[0].get_model()
34 particles = [h.get_particle()
for h
in hiers]
36 super().
__init__(model, label=label, weight=weight)
40 c3 = IMP.algebra.Vector3D(0, 0, 0)
41 elif type(center)
is IMP.algebra.Vector3D:
45 "%s: @param center must be an IMP.algebra.Vector3D object" % (
54 self.rs.add_restraint(r3)
58 """A simple distance restraint"""
60 def __init__(self, root_hier, tuple_selection1, tuple_selection2,
61 distancemin=0, distancemax=100, resolution=1.0, kappa=1.0,
62 label=
None, weight=1.):
63 """Setup distance restraint.
64 @param root_hier The hierarchy to select from
65 @param tuple_selection1 (resnum, resnum, molecule name, copy
67 @param tuple_selection2 (resnum, resnum, molecule name, copy
69 @param distancemin The minimum dist
70 @param distancemax The maximum dist
71 @param resolution For selecting particles
72 @param kappa The harmonic parameter
73 @param label A unique label to be used in outputs and
74 particle/restraint names
75 @param weight Weight of restraint
76 @note Pass the same resnum twice to each tuple_selection. Optionally
82 model = root_hier.get_model()
84 if len(tuple_selection1) > 3:
85 copy_num1 = tuple_selection1[3]
87 if len(tuple_selection2) > 3:
88 copy_num2 = tuple_selection2[3]
91 resolution=resolution,
92 molecule=tuple_selection1[2],
93 residue_index=tuple_selection1[0],
95 particles1 = sel1.get_selected_particles()
97 resolution=resolution,
98 molecule=tuple_selection2[2],
99 residue_index=tuple_selection2[0],
100 copy_index=copy_num2)
101 particles2 = sel2.get_selected_particles()
103 super().
__init__(model, label=label, weight=weight)
106 print(
"Created distance restraint between "
107 "%s and %s" % (particles1[0].get_name(),
108 particles2[0].get_name()))
110 if len(particles1) > 1
or len(particles2) > 1:
111 raise ValueError(
"more than one particle selected")
113 self.rs.add_restraint(
117 self.rs.add_restraint(
124 """Restrain particles within (or outside) a cylinder.
125 The cylinder is aligned along the z-axis and with center x=y=0.
126 Optionally, one can restrain the cylindrical angle
130 def __init__(self, m, objects, resolution, radius, mintheta=None,
131 maxtheta=
None, repulsive=
False, label=
'None'):
133 @param objects PMI2 objects to restrain
134 @param resolution the resolution you want the restraint to be applied
135 @param radius the radius of the cylinder
136 @param mintheta minimum cylindrical angle in degrees
137 @param maxtheta maximum cylindrical angle in degrees
138 @param repulsive If True, restrain the particles to be outside
139 of the cylinder instead of inside
140 @param label A unique label to be used in outputs and
141 particle/restraint names
143 super().
__init__(m,
"CylinderRestraint %1%")
146 self.softness_angle = 0.5
150 self.mintheta = mintheta
151 self.maxtheta = maxtheta
152 self.repulsive = repulsive
156 self.particles = [h.get_particle()
for h
in hierarchies]
159 def get_probability(self, p):
161 r = self.math.sqrt(xyz.get_x()**2+xyz.get_y()**2)
162 argvalue = (r-self.radius) / self.softness
165 prob = (1.0 - self.plateau) / (1.0 + self.math.exp(-argvalue))
168 def get_angle_probability(self, p):
170 angle = self.math.atan2(xyz.get_y(), xyz.get_x())*180.0/self.math.pi
171 anglediff = (angle - self.maxtheta + 180 + 360) % 360 - 180
172 argvalue1 = anglediff / self.softness_angle
173 anglediff = (angle - self.mintheta + 180 + 360) % 360 - 180
174 argvalue2 = -anglediff / self.softness_angle
175 prob = ((1.0-self.plateau)
176 / (1.0 + self.math.exp(-max(argvalue1, argvalue2))))
181 for p
in self.particles:
182 s += -self.math.log(1.0-self.get_probability(p))
183 if self.mintheta
is not None and self.maxtheta
is not None:
184 s += -self.math.log(1.0-self.get_angle_probability(p))
188 return self.particles
190 def add_to_model(self):
193 def get_output(self):
196 output[
"_TotalScore"] = str(score)
197 output[
"CylinderRestraint_" + self.label] = str(score)
202 '''Distance restraint with bistable potential
203 Authors: G. Bouvier, R. Pellarin. Pasteur Institute.
208 def __init__(self, m, p1, p2, dist1, dist2, sigma1, sigma2, weight1,
211 input two particles, the two equilibrium distances, their amplitudes,
212 and their weights (populations)
214 super().
__init__(m,
"BiStableDistanceRestraint %1%")
221 self.weight1 = weight1
222 self.weight2 = weight2
224 if self.weight1+self.weight2 != 1:
225 raise ValueError(
"The sum of the weights must be one")
229 self.particle_list = [p1, p2]
231 def gaussian(self, x, mu, sig, w):
232 return (w*self.np.exp(-self.np.power(x - mu, 2.)
233 / (2 * self.np.power(sig, 2.))))
237 prob = self.gaussian(dist, self.dist1, self.sigma1, self.weight1) + \
238 self.gaussian(dist, self.dist2, self.sigma2, self.weight2)
239 return -self.math.log(prob)
242 return self.particle_list
246 """Anchor a particle to a specific coordinate."""
248 def __init__(self, root_hier, tuple_selection,
249 anchor_point=IMP.algebra.Vector3D(0, 0, 0),
250 radius=10.0, kappa=10.0, resolution=1.0, weight=1.0,
252 """Setup distance restraint.
253 @param root_hier The hierarchy to select from
254 @param tuple_selection (resnum, resnum, molecule name,
256 @param anchor_point Point to which to restrain particle
257 (IMP.algebra.Vector3D object)
258 @param radius Maximum distance the particle can move from the
259 fixed point before it is restrained
260 @param kappa Strength of the harmonic restraint for point-particle
261 distance greater than the radius
262 @param resolution For selecting a particle
263 @param weight Weight of restraint
264 @param label A unique label to be used in outputs and
265 particle/restraint names
266 @note Pass the same resnum twice to each tuple_selection. Optionally
269 model = root_hier.get_model()
271 if len(tuple_selection) > 3:
272 copy_num1 = tuple_selection[3]
275 resolution=resolution,
276 molecule=tuple_selection[2],
277 residue_index=tuple_selection[0],
278 copy_index=copy_num1)
279 ps = sel1.get_selected_particles()
281 raise ValueError(
"More than one particle selected")
283 super().
__init__(model, label=label, weight=weight)
287 if anchor_point
is None:
288 c3 = IMP.algebra.Vector3D(0, 0, 0)
289 elif isinstance(anchor_point, IMP.algebra.Vector3D):
292 raise TypeError(
"anchor_point must be an algebra.Vector3D object")
299 self.rs.add_restraint(r3)
301 print(
"\n%s: Created distance_to_point_restraint between "
302 "%s and %s" % (self.name, ps[0].get_name(), c3))
306 """Restrain particles to be above, below, or inside a planar membrane.
307 The membrane is defined to lie on the xy plane with a given z
308 coordinate and thickness, and particles are restrained (by their
309 z coordinates) with a simple sigmoid score.
312 def __init__(self, hier, objects_above=None, objects_inside=None,
313 objects_below=
None, center=0.0, thickness=30.0,
314 softness=3.0, plateau=0.0000000001, resolution=1,
315 weight=1.0, label=
None):
316 """Setup the restraint.
318 @param objects_inside list or tuples of objects in membrane
319 (e.g. ['p1', (10, 30,'p2')])
320 @param objects_above list or tuples of objects above membrane
321 @param objects_below list or tuples of objects below membrane
322 @param thickness Thickness of the membrane along the z-axis
323 @param softness Softness of the limiter in the sigmoid function
324 @param plateau Parameter to set the probability (=1- plateau))
325 at the plateau phase of the sigmoid
326 @param weight Weight of restraint
327 @param label A unique label to be used in outputs and
328 particle/restraint names.
332 model = self.hier.get_model()
335 model, name=
"MembraneRestraint", label=label, weight=weight)
338 self.thickness = thickness
339 self.softness = softness
340 self.plateau = plateau
342 self.resolution = resolution
347 z_center.set_nuisance(self.center)
351 z_center.get_particle_index(),
357 self.particles_above = []
358 self.particles_inside = []
359 self.particles_below = []
363 for obj
in objects_above:
364 if isinstance(obj, (tuple, list)):
365 particles = self._select_from_tuple(obj)
366 elif isinstance(obj, str):
367 particles = self._select_from_string(obj)
369 raise TypeError(
"MembraneRestraint objects must be "
370 "(start, end, molecule) or a molecule "
371 "name, got %r" % (obj,))
372 mr.add_particles_above(particles)
373 self.particles_above += particles
377 for obj
in objects_inside:
378 if isinstance(obj, (tuple, list)):
379 particles = self._select_from_tuple(obj)
380 elif isinstance(obj, str):
381 particles = self._select_from_string(obj)
383 raise TypeError(
"MembraneRestraint objects must be "
384 "(start, end, molecule) or a molecule "
385 "name, got %r" % (obj,))
386 mr.add_particles_inside(particles)
387 self.particles_inside += particles
391 for obj
in objects_below:
392 if isinstance(obj, (tuple, list)):
393 particles = self._select_from_tuple(obj)
394 elif isinstance(obj, str):
395 particles = self._select_from_string(obj)
397 raise TypeError(
"MembraneRestraint objects must be "
398 "(start, end, molecule) or a molecule "
399 "name, got %r" % (obj,))
400 mr.add_particles_below(particles)
401 self.particles_below += particles
404 for side, particles
in ((1, self.particles_above),
405 (-1, self.particles_below),
406 (0, self.particles_inside)):
408 IMP.pmi.tools._set_membrane_side(p, side, self.center)
410 self.rs.add_restraint(mr)
412 def get_particles_above(self):
413 return self.particles_above
415 def get_particles_inside(self):
416 return self.particles_inside
418 def get_particles_below(self):
419 return self.particles_below
421 def _select_from_tuple(self, obj):
423 self.hier, molecule=obj[2],
424 residue_indexes=range(obj[0], obj[1]+1, 1),
425 resolution=self.resolution).get_selected_particles()
429 def _select_from_string(self, obj):
431 self.hier, molecule=obj,
432 resolution=self.resolution).get_selected_particles()
436 file_out=
'membrane_localization.mrc'):
437 """Create an MRC density file to visualize the membrane."""
438 offset = 5.0 * self.thickness
444 IMP.algebra.Vector3D(-self.center - xy_size,
445 -self.center - xy_size,
446 -self.center - offset),
447 IMP.algebra.Vector3D(self.center + xy_size, self.center + xy_size,
448 self.center + offset))
450 dheader.set_resolution(resolution)
453 for vox
in range(dmap.get_header().get_number_of_voxels()):
454 c = dmap.get_location_by_voxel(vox)
455 if self._is_membrane(c[2]) == 1:
456 dmap.set_value(c[0], c[1], c[2], 1.0)
458 dmap.set_value(c[0], c[1], c[2], 0.0)
460 IMP.em.write_map(dmap, file_out)
462 def _is_membrane(self, z):
463 if ((z-self.center) < self.thickness/2.0
and
464 (z-self.center) >= -self.thickness/2.0):
471 """Restrain residue/residues to bind to unknown location in a target"""
473 def __init__(self, hier, selection, cutoff=6., sigma=3., xi=0.01,
474 resolution=1.0, weight=1.0, label=
None):
477 @param hier Hierarchy of the system
478 @param selection Selection of residues and target;
479 syntax is (prot, r1, r2, target_prot) or
480 (prot1, r1, r2, target_prot, target_r1, target_r2)
481 @param cutoff Distance cutoff between selected segment and target
483 @param sigma Distance variance between selected fragments
484 @param xi Slope of a distance-linear scoring function that
485 funnels the score when the particles are too
487 @param resolution Resolution at which to apply restraint
488 @param weight Weight of the restraint
489 @param label Extra text to label the restraint so that it is
490 searchable in the output
493 m = self.hier.get_model()
496 m, name=
"ResidueProteinProximityRestraint", label=label,
502 self.resolution = resolution
505 print(
'selection', selection, isinstance(selection, tuple))
506 if (
not isinstance(selection, tuple)
507 and not isinstance(selection, list)):
508 raise ValueError(
"Selection should be a tuple or list")
509 if len(selection) < 4:
511 "Selection should be (prot, r1, r2, target_prot) or "
512 "(prot1, r1, r2, target_prot, target_r1, target_r2)")
515 self.prot1 = selection[0]
516 self.r1 = int(selection[1])
517 self.r2 = int(selection[2])
519 self.prot2 = selection[3]
520 if len(selection) == 6:
521 self.tr1 = int(selection[4])
522 self.tr2 = int(selection[5])
524 if self.r1 == self.r2:
526 self.hier, molecule=self.prot1, residue_index=self.r1,
527 resolution=self.resolution).get_selected_particles()
530 self.hier, molecule=self.prot1,
531 residue_indexes=range(self.r1, self.r2+1, 1),
532 resolution=self.resolution).get_selected_particles()
534 if len(selection) == 4:
536 self.hier, molecule=self.prot2,
537 resolution=self.resolution).get_selected_particles()
539 elif len(selection) == 6:
541 self.hier, molecule=self.prot2,
542 residue_indexes=range(self.tr1, self.tr2+1, 1),
543 resolution=self.resolution).get_selected_particles()
545 self.included_ps = sel_resi + sel_target
552 m, self.cutoff, self.sigma, self.xi,
True,
553 'ResidueProteinProximityRestraint')
555 print(
'Selected fragment and target lengths:', len(sel_resi),
571 br.add_pairs_container(self.cpc)
573 br.add_contribution_particles(sel_resi, sel_target)
576 yi = ((cutoff**2/(2*sigma**2)
577 - math.log(1/math.sqrt(2*math.pi*sigma*sigma))+cutoff*xi/2.)
579 interpolation_factor = -(cutoff/2.)*(xi-yi)
580 max_p = (math.exp(-((distance+slack)**2)/(2*sigma**2))
581 / math.sqrt(2*math.pi*sigma*sigma))
582 max_score = -math.log(max_p)
586 br.set_interpolation_factor(interpolation_factor)
587 br.set_max_score(max_score)
589 self.rs.add_restraint(br)
591 self.restraint_sets = [self.rs] + self.restraint_sets[1:]
594 """ Get particles in the close pair container """
595 return self.cpc.get_indexes()
597 def get_output(self):
599 score = self.weight * self.rs.unprotected_evaluate(
None)
600 output[
"ResidueProteinProximityRestraint_score_" + self.label] \
Applies a SingletonScore to each Singleton in a list.
static Nuisance setup_particle(Model *m, ParticleIndex pi)
def __init__
Setup distance restraint.
A simple 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)
virtual double unprotected_evaluate(DerivativeAccumulator *da) const
Return the unweighted score for the restraint.
def __init__
Setup the restraint.
Return all spatially-proximal pairs of particles (a,b) from the two SingletonContainers A and B...
Distance restraint between two particles.
double get_distance(XYZR a, XYZR b)
Compute the sphere distance between a and b.
Restrain residue/residues to bind to unknown location in a target.
Classes to handle different kinds of restraints.
def __init__
input two particles, the two equilibrium distances, their amplitudes, and their weights (populations)...
Class for sampling a density map from particles.
ParticleIndexPairs get_indexes(const ParticlePairsTemp &ps)
Get the indexes from a list of particle pairs.
def __init__
Setup external barrier restraint.
Store a list of ParticleIndexes.
Anchor a particle to a specific coordinate.
def create_membrane_density
Create an MRC density file to visualize the membrane.
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.
Restrain particles to be above, below, or inside a planar membrane.
Keeps all structures inside a sphere.
def __init__
Setup distance restraint.
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 get_container_pairs
Get particles in the close pair container.
The general base class for IMP exceptions.
Class to handle individual particles of a Model object.
Functionality for loading, creating, manipulating and scoring atomic structures.
Distance restraint with bistable potential Authors: G.
Select hierarchy particles identified by the biological name.
virtual ModelObjectsTemp do_get_inputs() const =0
Restrain particles within (or outside) a cylinder.
A restraint is a term in an IMP ScoringFunction.