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:
25 class DegreesOfFreedom(object):
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 [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0).
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 [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0). Check
57 out an [MD example here](pmi_2atomistic_8py-example.html).
59 def __init__(self,model):
63 self.rigid_bodies = []
64 self.flexible_beads = []
68 self.movers_particles_map=IMP.pmi.tools.OrderedDict()
70 self.movers_xyz_map={}
71 self.disabled_movers=[]
77 def _get_nonrigid_hiers(self, nonrigid_parts, rigid_hiers, resolution):
78 """Get Hierarchy objects for nonrigid parts. Make sure that they are
79 a subset of the rigid body Hierarchies."""
80 if not nonrigid_parts:
85 rb_idxs = set(h.get_particle_index()
for h
in rigid_hiers)
88 if p.get_index()
not in rb_idxs:
90 "You tried to create nonrigid members from "
91 "particles that aren't in the RigidBody!")
99 nonrigid_max_trans = 4.0,
102 """Create rigid body constraint and mover
103 @param rigid_parts Can be one of the following inputs:
104 IMP Hierarchy, PMI System/State/Molecule/TempResidue, a list/set
105 (of list/set) of them or a RigidBody object.
106 Must be uniform input, however. No mixing object types.
107 @param nonrigid_parts Same input format as rigid_parts.
108 Must be a subset of rigid_parts particles.
109 @param max_trans Maximum rigid body translation
110 @param max_rot Maximum rigid body rotation
111 @param nonrigid_max_trans Maximum step for the nonrigid (bead) particles
112 @param resolution Only used if you pass PMI objects. Probably you
114 @param name Rigid body name (if None, use IMP default)
115 @eturn (rb_movers,rb_object)
116 @note If you want all resolutions, pass PMI objects because this
117 function will get them all. Alternatively you can do your
118 selection elsewhere and just pass hierarchies.
141 "No hierarchies were passed to create_rigid_body()",
147 nr_hiers = self._get_nonrigid_hiers(nonrigid_parts, hiers, resolution)
150 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
202 """Create crankshaft moves from a set of SUPER rigid body mover from one molecule.
203 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
207 for length
in lengths:
208 for n
in range(len(hiers)-length):
209 hs=hiers[n+1:n+length]
211 self.
create_super_rigid_body(hs, max_trans=0.0,max_rot=0.05, axis=(hiers[n].get_particle(),hiers[n+length].get_particle()))
224 chain_min_length=
None,
225 chain_max_length=
None,
229 """Create SUPER rigid body mover from one or more hierarchies.
231 Can also create chain of SRBs. If you don't pass chain min/max,
232 it'll treat everything you pass as ONE rigid body.
233 If you DO pass chain min/max, it'll expect srb_parts is a list
234 and break it into bits.
235 @param srb_parts Can be one of the following inputs:
236 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
237 or a list/set (of list/set) of them.
238 Must be uniform input, however. No mixing object types.
239 @param max_trans Maximum super rigid body translation
240 @param max_rot Maximum super rigid body rotation
241 @param chain_min_length Create a CHAIN of super rigid bodies -
242 must provide list; this parameter is the minimum chain length.
243 @param chain_max_length Maximum chain length
244 @param resolution Only used if you pass PMI objects. Probably you
246 @param name The name of the SRB (hard to assign a good one
248 @param axis A tuple containing two particles which are used to
249 compute the rotation axis of the SRB. The default is None,
250 meaning that the rotation axis is random.
252 @note If you set the chain parameters, will NOT create an SRB from
253 all of them together, but rather in groups made from the
260 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 warn_about_slices=
False)
for h
in srb_parts]
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 mv = self._setup_srb(hs,max_trans,max_rot,axis)
285 mv.set_was_used(
True)
286 srb_movers.append(mv)
288 raise Exception(
"DegreesOfFreedom: SetupSuperRigidBody: if you want chain, specify min AND max")
289 self.movers += srb_movers
291 if len(srb_movers)>1:
292 for n,mv
in enumerate(srb_movers):
293 mv.set_name(name+
'_'+str(n))
295 srb_movers[0].set_name(name)
298 def _setup_srb(self,hiers,max_trans,max_rot,axis):
305 self.movers_particles_map[srbm]=[]
308 for xyz
in super_rigid_xyzs:
309 srbm.add_xyz_particle(xyz)
311 for rb
in super_rigid_rbs:
312 srbm.add_rigid_body_particle(rb)
324 """Create a chain of flexible beads
326 @param flex_parts Can be one of the following inputs:
327 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
328 or a list/set (of list/set) of them.
329 Must be uniform input, however. No mixing object types.
330 @param max_trans Maximum flexible bead translation
331 @param resolution Only used if you pass PMI objects. Probably
339 if not hiers
or len(hiers)==0:
341 'No hierarchies were passed to create_flexible_beads()',
348 raise Exception(
"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
363 """Create MC normal mover for nuisance particles.
364 We will add an easier interface to add all of them from a PMI restraint
365 @param nuisance_p The Nuisance particle (an ISD::Scale)
366 @param step_size The maximum step size for Monte Carlo
367 @param name The name of the mover, useful for better output reading.
374 mv.set_was_used(
True)
375 self.nuisances.append(nuisance_p)
376 self.movers.append(mv)
381 """Setup particles for MD simulation. Returns all particles, just
382 pass this to molecular_dynamics_sample_objects in ReplicaExchange0.
383 @param hspec Can be one of the following inputs:
384 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
385 Must be uniform input, however. No mixing object types.
391 model = hiers[0].get_model()
396 IMP.core.XYZ(model,p.get_index()).set_coordinates_are_optimized(
True)
397 model.add_attribute(vxkey,p.get_index(),0.0)
398 model.add_attribute(vykey,p.get_index(),0.0)
399 model.add_attribute(vzkey,p.get_index(),0.0)
409 """Create a symmetry constraint. Checks:
410 same number of particles
411 disable ANY movers involving symmetry copies
412 (later may support moving them WITH references,
413 but requires code to propagate constraint)
414 @param references Can be one of the following inputs:
415 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them
416 @param clones Same format as references
417 @param transform The transform that moves a clone onto a reference
418 IMP.algebra.Transformation3D
419 @param resolution Only used if you pass PMI objects.
420 If you have a multires system, assuming each are rigid
421 bodies you probably only need one resolution.
422 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
441 for ref,clone
in zip(ref_rbs,clones_rbs):
444 for ref,clone
in zip(ref_beads,clones_beads):
454 if type==
"RIGID_BODY":
456 p.set_name(
"RigidBody_Symmetry")
458 for cp
in [(10,0,0),(0,10,0),(0,0,10)]:
463 self.rigid_bodies.append(rb)
464 rb.set_coordinates_are_optimized(
True)
468 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
469 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
470 print(
'Created rigid body symmetry restraint')
471 self.movers_particles_map[rb_mover_tr]=[]
472 self.movers_particles_map[rb_mover_rt]=[]
473 self.movers_rb_map[rb_mover_tr]=[rb]
474 self.movers_rb_map[rb_mover_rt]=[rb]
478 self.movers.append(rb_mover_tr)
479 self.movers.append(rb_mover_rt)
480 self._rb2mov[rb] = [rb_mover_tr,rb_mover_rt]
484 self.model,[p.get_particle().
get_index()
for p
in clones_rbs+clones_beads])
486 self.model.add_score_state(c)
487 print(
'Created symmetry restraint for',len(ref_rbs),
'rigid bodies and',
488 len(ref_beads),
'flexible beads')
504 return 'DegreesOfFreedom: ' + \
505 "\n".join(repr(m)
for m
in self.movers)
508 '''Set up MC run with just flexible beads.
509 Optimization works much better when restraints
510 are already set up.'''
511 pts = IMP.pmi.tools.ParticleToSampleList()
513 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Flexible_Bead_" + str(n))
514 if len(pts.get_particles_to_sample()) > 0:
516 print(
"optimize_flexible_beads: optimizing %i flexible beads" % len(self.
get_flexible_beads()))
519 print(
"optimize_flexible_beads: no particle to optimize")
522 """Returns Enabled movers"""
523 if self.disabled_movers:
524 filtered_mover_list=[]
525 for mv
in self.movers:
526 if not mv
in self.disabled_movers:
527 filtered_mover_list.append(mv)
528 return filtered_mover_list
533 """Return all movers corresponding to individual beads"""
534 return self.fb_movers
537 """Return list of rigid body objects"""
538 return self.rigid_bodies
541 """Return all flexible beads, including nonrigid members of rigid bodies"""
542 return self.flexible_beads
545 """Fix the position of the particles by disabling the corresponding movers
546 @param objects Can be one of the following inputs:
547 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
548 Must be uniform input, however. No mixing object types.
549 @param mover_types further filter the mover type that will be disabled, it can be a list of IMP.core.RigidBodyMover,
550 IMP.core.BallMover etc etc if one wants to fix the corresponding rigid body, or the floppy bodies.
551 An empty mover_types list is interpreted as all possible movers.
552 It returns the list of fixed xyz particles (ie, floppy bodies/beads) and rigid bodies
553 whose movers were disabled
556 pmi_resolution=
'all',
561 if mover_types
is None: mover_types=[]
564 for mv, ps
in self.movers_particles_map.items():
566 if p
in inv_map: inv_map[p].append(mv)
567 else: inv_map[p]=[mv]
569 for h
in hierarchies:
571 for mv
in inv_map[h]:
572 if (type(mv)
in mover_types
or not mover_types):
574 if mv
in self.movers_rb_map:
575 fixed_rb|=set(self.movers_rb_map[mv])
576 if mv
in self.movers_xyz_map:
577 fixed_xyz|=set(self.movers_xyz_map[mv])
578 print(
"Fixing %s movers" %(str(len(list(tmp_set)))))
579 self.disabled_movers+=list(tmp_set)
580 return list(fixed_xyz),list(fixed_rb)
583 """Reenable all movers: previously fixed particles will be released"""
584 self.disabled_movers=[]
587 """Extract the nuisances from get_particles_to_sample()"""
589 pslist = r.get_particles_to_sample()
591 raise Exception(
"dof.get_nuisances_from_restraint(): the passed object does not have a "
592 "get_particles_to_sample() function")
595 if len(pslist[name])==3:
596 ps,maxtrans,is_sampled = pslist[name]
598 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.