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 [ReplicaExchange](@ref IMP::pmi::macros::ReplicaExchange).
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 [ReplicaExchange](@ref IMP::pmi::macros::ReplicaExchange). 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()
162 model.remove_particle(com)
170 rb.add_member(h.get_particle())
172 self.rigid_bodies.append(rb)
173 rb.set_coordinates_are_optimized(
True)
178 rb_mover.set_name(name)
179 rb_movers.append(rb_mover)
180 self.movers_particles_map[rb_mover] = []
181 self.movers_rb_map[rb_mover] = [rb]
182 rb_mover.set_was_used(
True)
189 self.flexible_beads.append(h)
191 rb.set_is_rigid_member(p.get_index(),
False)
193 p.set_is_optimized(fk,
True)
197 self.fb_movers.append(fbmv)
200 fbmv.set_was_used(
True)
201 rb_movers.append(fbmv)
203 self.movers += rb_movers
204 self._rb2mov[rb] = rb_movers
210 """Create crankshaft moves from a set of SUPER rigid body mover
212 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
216 for length
in lengths:
217 for n
in range(len(hiers)-length):
218 hs = hiers[n+1:n+length]
220 hs, max_trans=0.0, max_rot=0.05,
221 axis=(hiers[n].get_particle(),
222 hiers[n+length].get_particle()))
225 chain_min_length=
None, chain_max_length=
None,
226 resolution=
'all', name=
None, axis=
None):
227 """Create SUPER rigid body mover from one or more hierarchies.
229 Can also create chain of SRBs. If you don't pass chain min/max,
230 it'll treat everything you pass as ONE rigid body.
231 If you DO pass chain min/max, it'll expect srb_parts is a list
232 and break it into bits.
233 @param srb_parts Can be one of the following inputs:
234 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
235 or a list/set (of list/set) of them.
236 Must be uniform input, however. No mixing object types.
237 @param max_trans Maximum super rigid body translation
238 @param max_rot Maximum super rigid body rotation
239 @param chain_min_length Create a CHAIN of super rigid bodies -
240 must provide list; this parameter is the minimum
242 @param chain_max_length Maximum chain length
243 @param resolution Only used if you pass PMI objects. Probably you
245 @param name The name of the SRB (hard to assign a good one
247 @param axis A tuple containing two particles which are used to
248 compute the rotation axis of the SRB. The default is None,
249 meaning that the rotation axis is random.
251 @note If you set the chain parameters, will NOT create an SRB from
252 all of them together, but rather in groups made from the
259 if chain_min_length
is None and chain_max_length
is None:
265 'No hierarchies were passed to create_super_rigid_body()',
270 if not hasattr(srb_parts,
'__iter__'):
271 raise Exception(
"You tried to make a chain without a list!")
273 h, resolution, flatten=
True, warn_about_slices=
False)
277 if chain_min_length
is None and chain_max_length
is None:
278 mv = self._setup_srb(srb_groups, max_trans, max_rot, axis)
280 mv.set_was_used(
True)
281 srb_movers.append(mv)
282 elif chain_min_length
is not None and chain_max_length
is not None:
284 srb_groups, chain_min_length, chain_max_length):
285 mv = self._setup_srb(hs, max_trans, max_rot, axis)
287 mv.set_was_used(
True)
288 srb_movers.append(mv)
291 "DegreesOfFreedom: SetupSuperRigidBody: if you want "
292 "chain, specify min AND max")
293 self.movers += srb_movers
295 if len(srb_movers) > 1:
296 for n, mv
in enumerate(srb_movers):
297 mv.set_name(name +
'_' + str(n))
299 srb_movers[0].set_name(name)
302 def _setup_srb(self, hiers, max_trans, max_rot, axis):
305 hiers[0][0].get_model(), max_trans, max_rot)
308 hiers[0][0].get_model(), axis[0], axis[1], max_trans, max_rot)
309 srbm.set_name(
"Super rigid body transform mover")
310 srbm.set_was_used(
True)
311 super_rigid_rbs, super_rigid_xyzs \
314 self.movers_particles_map[srbm] = []
317 for xyz
in super_rigid_xyzs:
318 srbm.add_xyz_particle(xyz)
320 for rb
in super_rigid_rbs:
321 srbm.add_rigid_body_particle(rb)
330 """Create a chain of flexible beads
332 @param flex_parts Can be one of the following inputs:
333 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
334 or a list/set (of list/set) of them.
335 Must be uniform input, however. No mixing object types.
336 @param max_trans Maximum flexible bead translation
337 @param resolution Only used if you pass PMI objects. Probably
345 if not hiers
or len(hiers) == 0:
347 'No hierarchies were passed to create_flexible_beads()',
356 "Cannot create flexible beads from members of rigid body")
357 self.flexible_beads.append(h)
359 fb_movers.append(fbmv)
360 fbmv.set_was_used(
True)
361 self.fb_movers.append(fbmv)
364 self.movers += fb_movers
368 """Create MC normal mover for nuisance particles.
369 We will add an easier interface to add all of them from a PMI restraint
370 @param nuisance_p The Nuisance particle (an ISD::Scale)
371 @param step_size The maximum step size for Monte Carlo
372 @param name The name of the mover, useful for better output reading.
379 mv.set_was_used(
True)
380 self.nuisances.append(nuisance_p)
381 self.movers.append(mv)
385 """Setup particles for MD simulation. Returns all particles, just
386 pass this to molecular_dynamics_sample_objects in ReplicaExchange.
387 @param hspec Can be one of the following inputs:
388 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
389 or a list/set (of list/set) of them.
390 Must be uniform input, however. No mixing object types.
393 model = hiers[0].get_model()
399 pxyz.set_coordinates_are_optimized(
True)
400 IMP.atom.LinearVelocity.setup_particle(p, [0., 0., 0.])
405 resolution=
'all', type=
"AXIAL"):
406 """Create a symmetry constraint. Checks:
407 same number of particles
408 disable ANY movers involving symmetry copies
409 (later may support moving them WITH references,
410 but requires code to propagate constraint)
411 @param references Can be one of the following inputs:
412 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
413 or a list/set (of list/set) of them
414 @param clones Same format as references
415 @param transform The transform that moves a clone onto a reference
416 IMP.algebra.Transformation3D
417 @param resolution Only used if you pass PMI objects.
418 If you have a multires system, assuming each are rigid
419 bodies you probably only need one resolution.
420 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
431 for ref, clone
in zip(ref_rbs, clones_rbs):
434 for ref, clone
in zip(ref_beads, clones_beads):
443 if type ==
"RIGID_BODY":
445 p.set_name(
"RigidBody_Symmetry")
448 for cp
in [(10, 0, 0), (0, 10, 0), (0, 0, 10)]:
453 self.rigid_bodies.append(rb)
454 rb.set_coordinates_are_optimized(
True)
456 rb.get_model(), rb.get_particle_index(), 0.0, 1.0)
458 rb.get_model(), rb.get_particle_index(), 10.0, 0.0)
460 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
461 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
462 print(
'Created rigid body symmetry restraint')
463 self.movers_particles_map[rb_mover_tr] = []
464 self.movers_particles_map[rb_mover_rt] = []
465 self.movers_rb_map[rb_mover_tr] = [rb]
466 self.movers_rb_map[rb_mover_rt] = [rb]
468 self.movers_particles_map[rb_mover_tr] \
470 self.movers_particles_map[rb_mover_rt] \
472 self.movers.append(rb_mover_tr)
473 self.movers.append(rb_mover_rt)
475 self._rb2mov[rb] = [rb_mover_tr, rb_mover_rt]
480 for bead
in clones_rbs+clones_beads])
482 self.model.add_score_state(c)
483 print(
'Created symmetry restraint for', len(ref_rbs),
484 'rigid bodies and', len(ref_beads),
'flexible beads')
493 return 'DegreesOfFreedom: ' + \
494 "\n".join(repr(m)
for m
in self.movers)
497 '''Set up MC run with just flexible beads.
498 Optimization works much better when restraints
499 are already set up.'''
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 """Re-enable 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]
599 def _get_floppy_body_movers(fbs, maxtrans):
607 fb.set_is_optimized(fk,
True)
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
Re-enable 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 FloatKeys get_internal_coordinate_keys()
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.
static void teardown_particle(CenterOfMass com)
Make the particle no longer a center of mass.
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.