1 """@namespace IMP.pmi.dof
2 Create movers and set up constraints for PMI objects.
3 See the documentation of the DegreesOfFreedom class for more information.
6 from __future__
import print_function
18 def create_rigid_body_movers(dof, maxtrans, maxrot):
20 for rb
in dof.rigid_bodies:
26 class DegreesOfFreedom(object):
27 """Simplify creation of constraints and movers for an IMP Hierarchy.
29 * The various "create X" functions make movers for system components
30 as well as set up necessary constraints. For each of these functions,
31 you can generally pass PMI objects like
32 [Molecule](@ref IMP::pmi::topology::Molecule) or slices thereof.
33 * DegreesOfFreedom.create_rigid_body() lets you rigidify a molecule
34 (but allows you to also pass "nonrigid" components which move with
35 the body and also independently).
36 * DegreesOfFreedom.create_super_rigid_body() sets up a special
37 "Super Rigid Body" which moves rigidly but is not always constrained
38 to be rigid (so you can later move the parts separately). This is
39 good for speeding up sampling.
40 * DegreesOfFreedom.create_flexible_beads() sets up particles to move
42 * DegreesOfFreedom.setup_md() sets up particles to move with molecular
43 dynamics. Note that this is not (yet) compatible with rigid bodies,
44 and only works with some restraints.
45 * DegreesOfFreedom.constrain_symmetry() makes a symmetry constraint so
46 that clones automatically move with their references. If instead you
47 want a softer restraint, check out the
48 [SymmetryRestraint](@ref IMP::pmi::restraints::stereochemistry::SymmetryRestraint).
49 * When you are done you can access all movers with
50 DegreesOfFreedom.get_movers(). If you have set up rigid, super rigid,
51 or flexible beads, pass the movers to the `monte_carlo_sample_objects`
53 [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0).
54 * If you are running MD, you have to separately pass the particles
55 (also returned from DegreesOfFreedom.setup_md()) to the
56 `molecular_dynamics_sample_objects` argument of
57 [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0). Check
58 out an [MD example here](pmi_2atomistic_8py-example.html).
60 def __init__(self, model):
64 self.rigid_bodies = []
66 self.flexible_beads = []
71 self.movers_particles_map = IMP.pmi.tools.OrderedDict()
72 self.movers_rb_map = {}
73 self.movers_xyz_map = {}
74 self.disabled_movers = []
76 def _get_nonrigid_hiers(self, nonrigid_parts, rigid_hiers, resolution):
77 """Get Hierarchy objects for nonrigid parts. Make sure that they are
78 a subset of the rigid body Hierarchies."""
79 if not nonrigid_parts:
84 rb_idxs = set(h.get_particle_index()
for h
in rigid_hiers)
87 if p.get_index()
not in rb_idxs:
89 "You tried to create nonrigid members from "
90 "particles that aren't in the RigidBody!")
94 max_trans=4.0, max_rot=0.5, nonrigid_max_trans=4.0,
95 resolution=
'all', name=
None):
96 """Create rigid body constraint and mover
97 @param rigid_parts Can be one of the following inputs:
98 IMP Hierarchy, PMI System/State/Molecule/TempResidue, a list/set
99 (of list/set) of them or a RigidBody object.
100 Must be uniform input, however. No mixing object types.
101 @param nonrigid_parts Same input format as rigid_parts.
102 Must be a subset of rigid_parts particles.
103 @param max_trans Maximum rigid body translation
104 @param max_rot Maximum rigid body rotation
105 @param nonrigid_max_trans Maximum step for the nonrigid (bead)
107 @param resolution Only used if you pass PMI objects. Probably you
109 @param name Rigid body name (if None, use IMP default)
110 @return (rb_movers,rb_object)
111 @note If you want all resolutions, pass PMI objects because this
112 function will get them all. Alternatively you can do your
113 selection elsewhere and just pass hierarchies.
124 model = rb.get_model()
128 model.get_particle(i)))[0]
129 for i
in rb.get_member_particle_indexes()]
138 "No hierarchies were passed to create_rigid_body()",
144 nr_hiers = self._get_nonrigid_hiers(nonrigid_parts, hiers, resolution)
147 model = hiers[0].get_model()
163 rb.add_member(h.get_particle())
165 self.rigid_bodies.append(rb)
166 rb.set_coordinates_are_optimized(
True)
171 rb_mover.set_name(name)
172 rb_movers.append(rb_mover)
173 self.movers_particles_map[rb_mover] = []
174 self.movers_rb_map[rb_mover] = [rb]
175 rb_mover.set_was_used(
True)
182 self.flexible_beads.append(h)
184 rb.set_is_rigid_member(p.get_index(),
False)
186 p.set_is_optimized(fk,
True)
190 self.fb_movers.append(fbmv)
193 fbmv.set_was_used(
True)
194 rb_movers.append(fbmv)
196 self.movers += rb_movers
197 self._rb2mov[rb] = rb_movers
203 """Create crankshaft moves from a set of SUPER rigid body mover
205 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
209 for length
in lengths:
210 for n
in range(len(hiers)-length):
211 hs = hiers[n+1:n+length]
213 hs, max_trans=0.0, max_rot=0.05,
214 axis=(hiers[n].get_particle(),
215 hiers[n+length].get_particle()))
218 chain_min_length=
None, chain_max_length=
None,
219 resolution=
'all', name=
None, axis=
None):
220 """Create SUPER rigid body mover from one or more hierarchies.
222 Can also create chain of SRBs. If you don't pass chain min/max,
223 it'll treat everything you pass as ONE rigid body.
224 If you DO pass chain min/max, it'll expect srb_parts is a list
225 and break it into bits.
226 @param srb_parts Can be one of the following inputs:
227 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
228 or a list/set (of list/set) of them.
229 Must be uniform input, however. No mixing object types.
230 @param max_trans Maximum super rigid body translation
231 @param max_rot Maximum super rigid body rotation
232 @param chain_min_length Create a CHAIN of super rigid bodies -
233 must provide list; this parameter is the minimum
235 @param chain_max_length Maximum chain length
236 @param resolution Only used if you pass PMI objects. Probably you
238 @param name The name of the SRB (hard to assign a good one
240 @param axis A tuple containing two particles which are used to
241 compute the rotation axis of the SRB. The default is None,
242 meaning that the rotation axis is random.
244 @note If you set the chain parameters, will NOT create an SRB from
245 all of them together, but rather in groups made from the
252 if chain_min_length
is None and chain_max_length
is None:
258 'No hierarchies were passed to create_super_rigid_body()',
263 if not hasattr(srb_parts,
'__iter__'):
264 raise Exception(
"You tried to make a chain without a list!")
266 h, resolution, flatten=
True, warn_about_slices=
False)
270 if chain_min_length
is None and chain_max_length
is None:
271 mv = self._setup_srb(srb_groups, max_trans, max_rot, axis)
273 mv.set_was_used(
True)
274 srb_movers.append(mv)
275 elif chain_min_length
is not None and chain_max_length
is not None:
277 srb_groups, chain_min_length, chain_max_length):
278 mv = self._setup_srb(hs, max_trans, max_rot, axis)
280 mv.set_was_used(
True)
281 srb_movers.append(mv)
284 "DegreesOfFreedom: SetupSuperRigidBody: if you want "
285 "chain, specify min AND max")
286 self.movers += srb_movers
288 if len(srb_movers) > 1:
289 for n, mv
in enumerate(srb_movers):
290 mv.set_name(name +
'_' + str(n))
292 srb_movers[0].set_name(name)
295 def _setup_srb(self, hiers, max_trans, max_rot, axis):
298 hiers[0][0].get_model(), max_trans, max_rot)
301 hiers[0][0].get_model(), axis[0], axis[1], max_trans, max_rot)
302 srbm.set_was_used(
True)
303 super_rigid_rbs, super_rigid_xyzs \
306 self.movers_particles_map[srbm] = []
309 for xyz
in super_rigid_xyzs:
310 srbm.add_xyz_particle(xyz)
312 for rb
in super_rigid_rbs:
313 srbm.add_rigid_body_particle(rb)
322 """Create a chain of flexible beads
324 @param flex_parts Can be one of the following inputs:
325 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
326 or a list/set (of list/set) of them.
327 Must be uniform input, however. No mixing object types.
328 @param max_trans Maximum flexible bead translation
329 @param resolution Only used if you pass PMI objects. Probably
337 if not hiers
or len(hiers) == 0:
339 'No hierarchies were passed to create_flexible_beads()',
348 "Cannot create flexible beads from members of rigid body")
349 self.flexible_beads.append(h)
351 fb_movers.append(fbmv)
352 fbmv.set_was_used(
True)
353 self.fb_movers.append(fbmv)
356 self.movers += fb_movers
360 """Create MC normal mover for nuisance particles.
361 We will add an easier interface to add all of them from a PMI restraint
362 @param nuisance_p The Nuisance particle (an ISD::Scale)
363 @param step_size The maximum step size for Monte Carlo
364 @param name The name of the mover, useful for better output reading.
371 mv.set_was_used(
True)
372 self.nuisances.append(nuisance_p)
373 self.movers.append(mv)
377 """Setup particles for MD simulation. Returns all particles, just
378 pass this to molecular_dynamics_sample_objects in ReplicaExchange0.
379 @param hspec Can be one of the following inputs:
380 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
381 or a list/set (of list/set) of them.
382 Must be uniform input, however. No mixing object types.
388 model = hiers[0].get_model()
394 pxyz.set_coordinates_are_optimized(
True)
395 model.add_attribute(vxkey, p.get_index(), 0.0)
396 model.add_attribute(vykey, p.get_index(), 0.0)
397 model.add_attribute(vzkey, p.get_index(), 0.0)
402 resolution=
'all', type=
"AXIAL"):
403 """Create a symmetry constraint. Checks:
404 same number of particles
405 disable ANY movers involving symmetry copies
406 (later may support moving them WITH references,
407 but requires code to propagate constraint)
408 @param references Can be one of the following inputs:
409 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
410 or a list/set (of list/set) of them
411 @param clones Same format as references
412 @param transform The transform that moves a clone onto a reference
413 IMP.algebra.Transformation3D
414 @param resolution Only used if you pass PMI objects.
415 If you have a multires system, assuming each are rigid
416 bodies you probably only need one resolution.
417 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
428 for ref, clone
in zip(ref_rbs, clones_rbs):
431 for ref, clone
in zip(ref_beads, clones_beads):
440 if type ==
"RIGID_BODY":
442 p.set_name(
"RigidBody_Symmetry")
445 for cp
in [(10, 0, 0), (0, 10, 0), (0, 0, 10)]:
450 self.rigid_bodies.append(rb)
451 rb.set_coordinates_are_optimized(
True)
453 rb.get_model(), rb.get_particle_index(), 0.0, 1.0)
455 rb.get_model(), rb.get_particle_index(), 10.0, 0.0)
457 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
458 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
459 print(
'Created rigid body symmetry restraint')
460 self.movers_particles_map[rb_mover_tr] = []
461 self.movers_particles_map[rb_mover_rt] = []
462 self.movers_rb_map[rb_mover_tr] = [rb]
463 self.movers_rb_map[rb_mover_rt] = [rb]
465 self.movers_particles_map[rb_mover_tr] \
467 self.movers_particles_map[rb_mover_rt] \
469 self.movers.append(rb_mover_tr)
470 self.movers.append(rb_mover_rt)
472 self._rb2mov[rb] = [rb_mover_tr, rb_mover_rt]
477 for bead
in clones_rbs+clones_beads])
479 self.model.add_score_state(c)
480 print(
'Created symmetry restraint for', len(ref_rbs),
481 'rigid bodies and', len(ref_beads),
'flexible beads')
490 return 'DegreesOfFreedom: ' + \
491 "\n".join(repr(m)
for m
in self.movers)
494 '''Set up MC run with just flexible beads.
495 Optimization works much better when restraints
496 are already set up.'''
497 pts = IMP.pmi.tools.ParticleToSampleList()
499 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
500 "Flexible_Bead_" + str(n))
501 if len(pts.get_particles_to_sample()) > 0:
503 print(
"optimize_flexible_beads: optimizing %i flexible beads"
507 print(
"optimize_flexible_beads: no particle to optimize")
510 """Returns Enabled movers"""
511 if self.disabled_movers:
512 filtered_mover_list = []
513 for mv
in self.movers:
514 if mv
not in self.disabled_movers:
515 filtered_mover_list.append(mv)
516 return filtered_mover_list
521 """Return all movers corresponding to individual beads"""
522 return self.fb_movers
525 """Return list of rigid body objects"""
526 return self.rigid_bodies
529 "Return all flexible beads, including nonrigid members of rigid bodies"
530 return self.flexible_beads
533 """Fix the position of the particles by disabling the corresponding
535 @param objects Can be one of the following inputs:
536 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a
537 list/set (of list/set) of them.
538 Must be uniform input, however. No mixing object types.
539 @param mover_types further filter the mover type that will be
540 disabled; it can be a list of IMP.core.RigidBodyMover,
541 IMP.core.BallMover etc etc if one wants to fix the corresponding
542 rigid body, or the floppy bodies.
543 An empty mover_types list is interpreted as all possible movers.
544 It returns the list of fixed xyz particles (ie, floppy bodies/beads)
545 and rigid bodies whose movers were disabled
548 pmi_resolution=
'all',
553 if mover_types
is None:
557 for mv, ps
in self.movers_particles_map.items():
560 inv_map[p].append(mv)
564 for h
in hierarchies:
566 for mv
in inv_map[h]:
567 if (type(mv)
in mover_types
or not mover_types):
569 if mv
in self.movers_rb_map:
570 fixed_rb |= set(self.movers_rb_map[mv])
571 if mv
in self.movers_xyz_map:
572 fixed_xyz |= set(self.movers_xyz_map[mv])
573 print(
"Fixing %s movers" % (str(len(list(tmp_set)))))
574 self.disabled_movers += list(tmp_set)
575 return list(fixed_xyz), list(fixed_rb)
578 """Reenable all movers: previously fixed particles will be released"""
579 self.disabled_movers = []
582 """Extract the nuisances from get_particles_to_sample()"""
584 pslist = r.get_particles_to_sample()
585 except AttributeError:
587 "dof.get_nuisances_from_restraint(): the passed object "
588 "does not have a get_particles_to_sample() function")
591 if len(pslist[name]) == 3:
592 ps, maxtrans, is_sampled = pslist[name]
594 ps, maxtrans = pslist[name]
def optimize_flexible_beads
Set up MC run with just flexible beads.
def get_rigid_bodies
Return list of rigid body objects.
static CenterOfMass setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor members)
Apply a SingletonFunction to a SingletonContainer to maintain an invariant.
Set of Python classes to create a multi-state, multi-resolution IMP hierarchy.
def create_flexible_beads
Create a chain of flexible beads.
def enable_all_movers
Reenable all movers: previously fixed particles will be released.
def get_nuisances_from_restraint
Extract the nuisances from get_particles_to_sample()
Modify the transformation of a rigid body.
def create_nuisance_mover
Create MC normal mover for nuisance particles.
def get_movers
Returns Enabled movers.
def get_floppy_body_movers
Return all movers corresponding to individual beads.
Move continuous particle variables by perturbing them within a ball.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
GenericHierarchies get_leaves(Hierarchy mhd)
Get all the leaves of the bit of hierarchy.
static XYZ setup_particle(Model *m, ParticleIndex pi)
def setup_md
Setup particles for MD simulation.
def create_main_chain_mover
Create crankshaft moves from a set of SUPER rigid body mover from one molecule.
def create_rigid_body
Create rigid body constraint and mover.
The standard decorator for manipulating molecular structures.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
def create_super_rigid_body
Create SUPER rigid body mover from one or more hierarchies.
Store a list of ParticleIndexes.
A decorator for a particle with x,y,z coordinates.
Modify a set of continuous variables using a normal distribution.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
Sample using Monte Carlo.
The general base class for IMP exceptions.
static Reference setup_particle(Model *m, ParticleIndex pi, ParticleIndexAdaptor reference)
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
Class to handle individual particles of a Model object.
def constrain_symmetry
Create a symmetry constraint.
Python classes to represent, score, sample and analyze models.
A decorator for a rigid body.
Functionality for loading, creating, manipulating and scoring atomic structures.
Hierarchies get_leaves(const Selection &h)
def get_flexible_beads
Return all flexible beads, including nonrigid members of rigid bodies.
def disable_movers
Fix the position of the particles by disabling the corresponding movers.
static RigidBody setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor ps)
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Warning for probably incorrect input parameters.