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.
17 def create_rigid_body_movers(dof, maxtrans, maxrot):
19 for rb
in dof.rigid_bodies:
25 class DegreesOfFreedom:
26 """Simplify creation of constraints and movers for an IMP Hierarchy.
28 * The various "create X" functions make movers for system components
29 as well as set up necessary constraints. For each of these functions,
30 you can generally pass PMI objects like
31 [Molecule](@ref IMP::pmi::topology::Molecule) or slices thereof.
32 * DegreesOfFreedom.create_rigid_body() lets you rigidify a molecule
33 (but allows you to also pass "nonrigid" components which move with
34 the body and also independently).
35 * DegreesOfFreedom.create_super_rigid_body() sets up a special
36 "Super Rigid Body" which moves rigidly but is not always constrained
37 to be rigid (so you can later move the parts separately). This is
38 good for speeding up sampling.
39 * DegreesOfFreedom.create_flexible_beads() sets up particles to move
41 * DegreesOfFreedom.setup_md() sets up particles to move with molecular
42 dynamics. Note that this is not (yet) compatible with rigid bodies,
43 and only works with some restraints.
44 * DegreesOfFreedom.constrain_symmetry() makes a symmetry constraint so
45 that clones automatically move with their references. If instead you
46 want a softer restraint, check out the
47 [SymmetryRestraint](@ref IMP::pmi::restraints::stereochemistry::SymmetryRestraint).
48 * When you are done you can access all movers with
49 DegreesOfFreedom.get_movers(). If you have set up rigid, super rigid,
50 or flexible beads, pass the movers to the `monte_carlo_sample_objects`
52 [ReplicaExchange](@ref IMP::pmi::macros::ReplicaExchange).
53 * If you are running MD, you have to separately pass the particles
54 (also returned from DegreesOfFreedom.setup_md()) to the
55 `molecular_dynamics_sample_objects` argument of
56 [ReplicaExchange](@ref IMP::pmi::macros::ReplicaExchange). Check
57 out an [MD example here](pmi_2atomistic_8py-example.html).
59 def __init__(self, model):
63 self.rigid_bodies = []
65 self.flexible_beads = []
70 self.movers_particles_map = IMP.pmi.tools.OrderedDict()
71 self.movers_rb_map = {}
72 self.movers_xyz_map = {}
73 self.disabled_movers = []
75 def _get_nonrigid_hiers(self, nonrigid_parts, rigid_hiers, resolution):
76 """Get Hierarchy objects for nonrigid parts. Make sure that they are
77 a subset of the rigid body Hierarchies."""
78 if not nonrigid_parts:
83 rb_idxs = set(h.get_particle_index()
for h
in rigid_hiers)
86 if p.get_index()
not in rb_idxs:
88 "You tried to create nonrigid members from "
89 "particles that aren't in the RigidBody!")
93 max_trans=4.0, max_rot=0.5, nonrigid_max_trans=4.0,
94 resolution=
'all', name=
None):
95 """Create rigid body constraint and mover
96 @param rigid_parts Can be one of the following inputs:
97 IMP Hierarchy, PMI System/State/Molecule/TempResidue, a list/set
98 (of list/set) of them or a RigidBody object.
99 Must be uniform input, however. No mixing object types.
100 @param nonrigid_parts Same input format as rigid_parts.
101 Must be a subset of rigid_parts particles.
102 @param max_trans Maximum rigid body translation
103 @param max_rot Maximum rigid body rotation
104 @param nonrigid_max_trans Maximum step for the nonrigid (bead)
106 @param resolution Only used if you pass PMI objects. Probably you
108 @param name Rigid body name (if None, use IMP default)
109 @return (rb_movers,rb_object)
110 @note If you want all resolutions, pass PMI objects because this
111 function will get them all. Alternatively you can do your
112 selection elsewhere and just pass hierarchies.
123 model = rb.get_model()
127 model.get_particle(i)))[0]
128 for i
in rb.get_member_particle_indexes()]
137 "No hierarchies were passed to create_rigid_body()",
143 nr_hiers = self._get_nonrigid_hiers(nonrigid_parts, hiers, resolution)
146 model = hiers[0].get_model()
161 model.remove_particle(com)
169 rb.add_member(h.get_particle())
171 self.rigid_bodies.append(rb)
172 rb.set_coordinates_are_optimized(
True)
177 rb_mover.set_name(name)
178 rb_movers.append(rb_mover)
179 self.movers_particles_map[rb_mover] = []
180 self.movers_rb_map[rb_mover] = [rb]
181 rb_mover.set_was_used(
True)
188 self.flexible_beads.append(h)
190 rb.set_is_rigid_member(p.get_index(),
False)
192 p.set_is_optimized(fk,
True)
196 self.fb_movers.append(fbmv)
199 fbmv.set_was_used(
True)
200 rb_movers.append(fbmv)
202 self.movers += rb_movers
203 self._rb2mov[rb] = rb_movers
209 """Create crankshaft moves from a set of SUPER rigid body mover
211 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
215 for length
in lengths:
216 for n
in range(len(hiers)-length):
217 hs = hiers[n+1:n+length]
219 hs, max_trans=0.0, max_rot=0.05,
220 axis=(hiers[n].get_particle(),
221 hiers[n+length].get_particle()))
224 chain_min_length=
None, chain_max_length=
None,
225 resolution=
'all', name=
None, axis=
None):
226 """Create SUPER rigid body mover from one or more hierarchies.
228 Can also create chain of SRBs. If you don't pass chain min/max,
229 it'll treat everything you pass as ONE rigid body.
230 If you DO pass chain min/max, it'll expect srb_parts is a list
231 and break it into bits.
232 @param srb_parts Can be one of the following inputs:
233 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
234 or a list/set (of list/set) of them.
235 Must be uniform input, however. No mixing object types.
236 @param max_trans Maximum super rigid body translation
237 @param max_rot Maximum super rigid body rotation
238 @param chain_min_length Create a CHAIN of super rigid bodies -
239 must provide list; this parameter is the minimum
241 @param chain_max_length Maximum chain length
242 @param resolution Only used if you pass PMI objects. Probably you
244 @param name The name of the SRB (hard to assign a good one
246 @param axis A tuple containing two particles which are used to
247 compute the rotation axis of the SRB. The default is None,
248 meaning that the rotation axis is random.
250 @note If you set the chain parameters, will NOT create an SRB from
251 all of them together, but rather in groups made from the
258 if chain_min_length
is None and chain_max_length
is None:
264 'No hierarchies were passed to create_super_rigid_body()',
269 if not hasattr(srb_parts,
'__iter__'):
270 raise Exception(
"You tried to make a chain without a list!")
272 h, resolution, flatten=
True, warn_about_slices=
False)
276 if chain_min_length
is None and chain_max_length
is None:
277 mv = self._setup_srb(srb_groups, max_trans, max_rot, axis)
279 mv.set_was_used(
True)
280 srb_movers.append(mv)
281 elif chain_min_length
is not None and chain_max_length
is not None:
283 srb_groups, chain_min_length, chain_max_length):
284 mv = self._setup_srb(hs, max_trans, max_rot, axis)
286 mv.set_was_used(
True)
287 srb_movers.append(mv)
290 "DegreesOfFreedom: SetupSuperRigidBody: if you want "
291 "chain, specify min AND max")
292 self.movers += srb_movers
294 if len(srb_movers) > 1:
295 for n, mv
in enumerate(srb_movers):
296 mv.set_name(name +
'_' + str(n))
298 srb_movers[0].set_name(name)
301 def _setup_srb(self, hiers, max_trans, max_rot, axis):
304 hiers[0][0].get_model(), max_trans, max_rot)
307 hiers[0][0].get_model(), axis[0], axis[1], max_trans, max_rot)
308 srbm.set_name(
"Super rigid body transform mover")
309 srbm.set_was_used(
True)
310 super_rigid_rbs, super_rigid_xyzs \
313 self.movers_particles_map[srbm] = []
316 for xyz
in super_rigid_xyzs:
317 srbm.add_xyz_particle(xyz)
319 for rb
in super_rigid_rbs:
320 srbm.add_rigid_body_particle(rb)
329 """Create a chain of flexible beads
331 @param flex_parts Can be one of the following inputs:
332 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
333 or a list/set (of list/set) of them.
334 Must be uniform input, however. No mixing object types.
335 @param max_trans Maximum flexible bead translation
336 @param resolution Only used if you pass PMI objects. Probably
344 if not hiers
or len(hiers) == 0:
346 'No hierarchies were passed to create_flexible_beads()',
355 "Cannot create flexible beads from members of rigid body")
356 self.flexible_beads.append(h)
358 fb_movers.append(fbmv)
359 fbmv.set_was_used(
True)
360 self.fb_movers.append(fbmv)
363 self.movers += fb_movers
367 """Create MC normal mover for nuisance particles.
368 We will add an easier interface to add all of them from a PMI restraint
369 @param nuisance_p The Nuisance particle (an ISD::Scale)
370 @param step_size The maximum step size for Monte Carlo
371 @param name The name of the mover, useful for better output reading.
378 mv.set_was_used(
True)
379 self.nuisances.append(nuisance_p)
380 self.movers.append(mv)
384 """Setup particles for MD simulation. Returns all particles, just
385 pass this to molecular_dynamics_sample_objects in ReplicaExchange.
386 @param hspec Can be one of the following inputs:
387 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
388 or a list/set (of list/set) of them.
389 Must be uniform input, however. No mixing object types.
392 model = hiers[0].get_model()
398 pxyz.set_coordinates_are_optimized(
True)
399 IMP.atom.LinearVelocity.setup_particle(p, [0., 0., 0.])
404 resolution=
'all', type=
"AXIAL"):
405 """Create a symmetry constraint. Checks:
406 same number of particles
407 disable ANY movers involving symmetry copies
408 (later may support moving them WITH references,
409 but requires code to propagate constraint)
410 @param references Can be one of the following inputs:
411 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
412 or a list/set (of list/set) of them
413 @param clones Same format as references
414 @param transform The transform that moves a clone onto a reference
415 IMP.algebra.Transformation3D
416 @param resolution Only used if you pass PMI objects.
417 If you have a multires system, assuming each are rigid
418 bodies you probably only need one resolution.
419 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
430 for ref, clone
in zip(ref_rbs, clones_rbs):
433 for ref, clone
in zip(ref_beads, clones_beads):
442 if type ==
"RIGID_BODY":
444 p.set_name(
"RigidBody_Symmetry")
447 for cp
in [(10, 0, 0), (0, 10, 0), (0, 0, 10)]:
452 self.rigid_bodies.append(rb)
453 rb.set_coordinates_are_optimized(
True)
455 rb.get_model(), rb.get_particle_index(), 0.0, 1.0)
457 rb.get_model(), rb.get_particle_index(), 10.0, 0.0)
459 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
460 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
461 print(
'Created rigid body symmetry restraint')
462 self.movers_particles_map[rb_mover_tr] = []
463 self.movers_particles_map[rb_mover_rt] = []
464 self.movers_rb_map[rb_mover_tr] = [rb]
465 self.movers_rb_map[rb_mover_rt] = [rb]
467 self.movers_particles_map[rb_mover_tr] \
469 self.movers_particles_map[rb_mover_rt] \
471 self.movers.append(rb_mover_tr)
472 self.movers.append(rb_mover_rt)
474 self._rb2mov[rb] = [rb_mover_tr, rb_mover_rt]
479 for bead
in clones_rbs+clones_beads])
481 self.model.add_score_state(c)
482 print(
'Created symmetry restraint for', len(ref_rbs),
483 'rigid bodies and', len(ref_beads),
'flexible beads')
492 return 'DegreesOfFreedom: ' + \
493 "\n".join(repr(m)
for m
in self.movers)
496 '''Set up MC run with just flexible beads.
497 Optimization works much better when restraints
498 are already set up.'''
502 print(
"optimize_flexible_beads: optimizing %i flexible beads"
506 print(
"optimize_flexible_beads: no particle to optimize")
509 """Returns Enabled movers"""
510 if self.disabled_movers:
511 filtered_mover_list = []
512 for mv
in self.movers:
513 if mv
not in self.disabled_movers:
514 filtered_mover_list.append(mv)
515 return filtered_mover_list
520 """Return all movers corresponding to individual beads"""
521 return self.fb_movers
524 """Return list of rigid body objects"""
525 return self.rigid_bodies
528 "Return all flexible beads, including nonrigid members of rigid bodies"
529 return self.flexible_beads
532 """Fix the position of the particles by disabling the corresponding
534 @param objects Can be one of the following inputs:
535 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a
536 list/set (of list/set) of them.
537 Must be uniform input, however. No mixing object types.
538 @param mover_types further filter the mover type that will be
539 disabled; it can be a list of IMP.core.RigidBodyMover,
540 IMP.core.BallMover etc etc if one wants to fix the corresponding
541 rigid body, or the floppy bodies.
542 An empty mover_types list is interpreted as all possible movers.
543 It returns the list of fixed xyz particles (ie, floppy bodies/beads)
544 and rigid bodies whose movers were disabled
547 pmi_resolution=
'all',
552 if mover_types
is None:
556 for mv, ps
in self.movers_particles_map.items():
559 inv_map[p].append(mv)
563 for h
in hierarchies:
565 for mv
in inv_map[h]:
566 if (type(mv)
in mover_types
or not mover_types):
568 if mv
in self.movers_rb_map:
569 fixed_rb |= set(self.movers_rb_map[mv])
570 if mv
in self.movers_xyz_map:
571 fixed_xyz |= set(self.movers_xyz_map[mv])
572 print(
"Fixing %s movers" % (str(len(list(tmp_set)))))
573 self.disabled_movers += list(tmp_set)
574 return list(fixed_xyz), list(fixed_rb)
577 """Re-enable all movers: previously fixed particles will be released"""
578 self.disabled_movers = []
581 """Extract the nuisances from get_particles_to_sample()"""
583 pslist = r.get_particles_to_sample()
584 except AttributeError:
586 "dof.get_nuisances_from_restraint(): the passed object "
587 "does not have a get_particles_to_sample() function")
590 if len(pslist[name]) == 3:
591 ps, maxtrans, is_sampled = pslist[name]
593 ps, maxtrans = pslist[name]
598 def _get_floppy_body_movers(fbs, maxtrans):
606 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.