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):
303 srbm.set_was_used(
True)
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)
325 """Create a chain of flexible beads
327 @param flex_parts Can be one of the following inputs:
328 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
329 or a list/set (of list/set) of them.
330 Must be uniform input, however. No mixing object types.
331 @param max_trans Maximum flexible bead translation
332 @param resolution Only used if you pass PMI objects. Probably
340 if not hiers
or len(hiers)==0:
342 'No hierarchies were passed to create_flexible_beads()',
349 raise Exception(
"Cannot create flexible beads from members of rigid body")
350 self.flexible_beads.append(h)
352 fb_movers.append(fbmv)
353 fbmv.set_was_used(
True)
354 self.fb_movers.append(fbmv)
357 self.movers += fb_movers
364 """Create MC normal mover for nuisance particles.
365 We will add an easier interface to add all of them from a PMI restraint
366 @param nuisance_p The Nuisance particle (an ISD::Scale)
367 @param step_size The maximum step size for Monte Carlo
368 @param name The name of the mover, useful for better output reading.
375 mv.set_was_used(
True)
376 self.nuisances.append(nuisance_p)
377 self.movers.append(mv)
382 """Setup particles for MD simulation. Returns all particles, just
383 pass this to molecular_dynamics_sample_objects in ReplicaExchange0.
384 @param hspec Can be one of the following inputs:
385 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
386 Must be uniform input, however. No mixing object types.
392 model = hiers[0].get_model()
397 IMP.core.XYZ(model,p.get_index()).set_coordinates_are_optimized(
True)
398 model.add_attribute(vxkey,p.get_index(),0.0)
399 model.add_attribute(vykey,p.get_index(),0.0)
400 model.add_attribute(vzkey,p.get_index(),0.0)
410 """Create a symmetry constraint. Checks:
411 same number of particles
412 disable ANY movers involving symmetry copies
413 (later may support moving them WITH references,
414 but requires code to propagate constraint)
415 @param references Can be one of the following inputs:
416 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them
417 @param clones Same format as references
418 @param transform The transform that moves a clone onto a reference
419 IMP.algebra.Transformation3D
420 @param resolution Only used if you pass PMI objects.
421 If you have a multires system, assuming each are rigid
422 bodies you probably only need one resolution.
423 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
442 for ref,clone
in zip(ref_rbs,clones_rbs):
445 for ref,clone
in zip(ref_beads,clones_beads):
455 if type==
"RIGID_BODY":
457 p.set_name(
"RigidBody_Symmetry")
459 for cp
in [(10,0,0),(0,10,0),(0,0,10)]:
464 self.rigid_bodies.append(rb)
465 rb.set_coordinates_are_optimized(
True)
469 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
470 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
471 print(
'Created rigid body symmetry restraint')
472 self.movers_particles_map[rb_mover_tr]=[]
473 self.movers_particles_map[rb_mover_rt]=[]
474 self.movers_rb_map[rb_mover_tr]=[rb]
475 self.movers_rb_map[rb_mover_rt]=[rb]
479 self.movers.append(rb_mover_tr)
480 self.movers.append(rb_mover_rt)
481 self._rb2mov[rb] = [rb_mover_tr,rb_mover_rt]
485 self.model,[p.get_particle().
get_index()
for p
in clones_rbs+clones_beads])
487 self.model.add_score_state(c)
488 print(
'Created symmetry restraint for',len(ref_rbs),
'rigid bodies and',
489 len(ref_beads),
'flexible beads')
505 return 'DegreesOfFreedom: ' + \
506 "\n".join(repr(m)
for m
in self.movers)
509 '''Set up MC run with just flexible beads.
510 Optimization works much better when restraints
511 are already set up.'''
512 pts = IMP.pmi.tools.ParticleToSampleList()
514 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Flexible_Bead_" + str(n))
515 if len(pts.get_particles_to_sample()) > 0:
517 print(
"optimize_flexible_beads: optimizing %i flexible beads" % len(self.
get_flexible_beads()))
520 print(
"optimize_flexible_beads: no particle to optimize")
523 """Returns Enabled movers"""
524 if self.disabled_movers:
525 filtered_mover_list=[]
526 for mv
in self.movers:
527 if not mv
in self.disabled_movers:
528 filtered_mover_list.append(mv)
529 return filtered_mover_list
534 """Return all movers corresponding to individual beads"""
535 return self.fb_movers
538 """Return list of rigid body objects"""
539 return self.rigid_bodies
542 """Return all flexible beads, including nonrigid members of rigid bodies"""
543 return self.flexible_beads
546 """Fix the position of the particles by disabling the corresponding movers
547 @param objects Can be one of the following inputs:
548 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
549 Must be uniform input, however. No mixing object types.
550 @param mover_types further filter the mover type that will be disabled, it can be a list of IMP.core.RigidBodyMover,
551 IMP.core.BallMover etc etc if one wants to fix the corresponding rigid body, or the floppy bodies.
552 An empty mover_types list is interpreted as all possible movers.
553 It returns the list of fixed xyz particles (ie, floppy bodies/beads) and rigid bodies
554 whose movers were disabled
557 pmi_resolution=
'all',
562 if mover_types
is None: mover_types=[]
565 for mv, ps
in self.movers_particles_map.items():
567 if p
in inv_map: inv_map[p].append(mv)
568 else: inv_map[p]=[mv]
570 for h
in hierarchies:
572 for mv
in inv_map[h]:
573 if (type(mv)
in mover_types
or not mover_types):
575 if mv
in self.movers_rb_map:
576 fixed_rb|=set(self.movers_rb_map[mv])
577 if mv
in self.movers_xyz_map:
578 fixed_xyz|=set(self.movers_xyz_map[mv])
579 print(
"Fixing %s movers" %(str(len(list(tmp_set)))))
580 self.disabled_movers+=list(tmp_set)
581 return list(fixed_xyz),list(fixed_rb)
584 """Reenable all movers: previously fixed particles will be released"""
585 self.disabled_movers=[]
588 """Extract the nuisances from get_particles_to_sample()"""
590 pslist = r.get_particles_to_sample()
592 raise Exception(
"dof.get_nuisances_from_restraint(): the passed object does not have a "
593 "get_particles_to_sample() function")
596 if len(pslist[name])==3:
597 ps,maxtrans,is_sampled = pslist[name]
599 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.