1 """@namespace IMP.pmi.dof
2 Create movers and setup constraints for PMI objects.
3 * Start by creating the DegreesOfFreedom class with `dof = IMP::pmi::dof::DegreesOfFreedom(model)`
4 * The various "create X" functions make movers for system components as well as setup necessary constraints.
5 For each of these functions, you can generally pass PMI objects like [Molecule](@ref IMP::pmi::topology::Molecule) or slices thereof.
6 * DegreesOfFreedom.create_rigid_body() lets you rigidify a molecule (but allows you to also pass "nonrigid" components which move with the body and also independently).
7 * DegreesOfFreedom.create_super_rigid_body() sets up a special "Super Rigid Body" which moves
8 rigidly but is not always constrained to be rigid (so you can later move the parts separately). Good for speeding up sampling.
9 * DegreesOfFreedom.create_flexible_beads() sets up particles to move individually.
10 * DegreesOfFreedom.setup_md() sets up particles to move with molecular dynamics. Note that this is not (yet) compatible with rigid bodies, and only some restraints.
11 * DegreesOfFreedom.constrain_symmetry() makes a symmetry constraint so that clones automatically move with their references. If instead you want a softer restraint, check out the [SymmetryRestraint](@ref IMP::pmi::restraints::stereochemistry::SymmetryRestraint).
12 * When you are done you can access all movers with DegreesOfFreedom.get_movers(). If you have set up rigid, super rigid, or flexible beads, pass the movers to the `monte_carlo_sample_objects` argument of [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0).
13 * If you are running MD, you have to separately pass the particles (also returned from DegreesOfFreedom.setup_md()) to the `molecular_dynamics_sample_objects` argument of [ReplicaExchange0](@ref IMP::pmi::macros::ReplicaExchange0). Check out an [MD example here](pmi_2atomistic_8py-example.html).
16 from __future__
import print_function
28 def create_rigid_body_movers(dof,maxtrans,maxrot):
30 for rb
in dof.rigid_bodies:
36 """A class to simplify create of constraints and movers for an IMP Hierarchy.
37 Call the various create() functions to get started.
38 Can get all enabled movers with get_movers(). Pass this to ReplicaExchange0.
40 def __init__(self,mdl):
44 self.rigid_bodies = []
45 self.flexible_beads = []
49 self.movers_particles_map=IMP.pmi.tools.OrderedDict()
51 self.movers_xyz_map={}
52 self.disabled_movers=[]
63 nonrigid_max_trans = 4.0,
66 """Create rigid body constraint and mover
67 @param rigid_parts Can be one of the following inputs:
68 IMP Hierarchy, PMI System/State/Molecule/TempResidue, a list/set (of list/set) of them
69 or a RigidBody object.
70 Must be uniform input, however. No mixing object types.
71 @param nonrigid_parts Same input format as rigid_parts.
72 Must be a subset of rigid_parts particles.
73 @param max_trans Maximum rigid body translation
74 @param max_rot Maximum rigid body rotation
75 @param nonrigid_max_trans Maximum step for the nonrigid (bead) particles
76 @param resolution Only used if you pass PMI objects. Probably you want 'all'.
77 @param name Rigid body name (if None, use IMP default)
78 \note If you want all resolutions, pass PMI objects because this function will get them all.
79 Alternatively you can do your selection elsewhere and just pass hierarchies.
80 Returns tuple (rb_movers,rb_object)
89 print(
"WARNING: Rigid Body Already Setup")
101 model=hiers[0].get_model()
103 print(
"WARNING: No hierarchies were passed to create_rigid_body()")
117 rb.add_member(h.get_particle())
119 self.rigid_bodies.append(rb)
120 rb.set_coordinates_are_optimized(
True)
125 rb_mover.set_name(name)
126 rb_movers.append(rb_mover)
127 self.movers_particles_map[rb_mover]=[]
128 self.movers_rb_map[rb_mover]=[rb]
129 rb_mover.set_was_used(
True)
139 rb_idxs = set(rb.get_member_indexes())
141 self.flexible_beads.append(h)
143 if not p.get_index()
in rb_idxs:
144 raise Exception(
"You tried to create nonrigid members from "
145 "particles that aren't in the RigidBody!")
147 rb.set_is_rigid_member(p.get_index(),
False)
149 p.set_is_optimized(fk,
True)
153 self.fb_movers.append(fbmv)
156 fbmv.set_was_used(
True)
157 rb_movers.append(fbmv)
159 self.movers += rb_movers
160 self._rb2mov[rb] = rb_movers
165 """Create crankshaft moves from a set of SUPER rigid body mover from one molecule.
166 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
170 for length
in lengths:
171 for n
in range(len(hiers)-length):
172 hs=hiers[n+1:n+length]
174 self.
create_super_rigid_body(hs, max_trans=0.0,max_rot=0.05, axis=(hiers[n].get_particle(),hiers[n+length].get_particle()))
187 chain_min_length=
None,
188 chain_max_length=
None,
192 """Create SUPER rigid body mover from one or more hierarchies. Can also create chain of SRBs.
193 If you don't pass chain min/max, it'll treat everything you pass as ONE rigid body.
194 If you DO pass chain min/max, it'll expect srb_parts is a list and break it into bits.
195 @param srb_parts Can be one of the following inputs:
196 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
197 Must be uniform input, however. No mixing object types.
198 @param max_trans Maximum super rigid body translation
199 @param max_rot Maximum super rigid body rotation
200 @param chain_min_length Create a CHAIN of super rigid bodies - must provide list
201 This parameter is the minimum chain length.
202 @param chain_max_length Maximum chain length
203 @param resolution Only used if you pass PMI objects. Probably you want 'all'.
204 @param name The name of the SRB (hard to assign a good one automatically)
205 @param axis A tuple containing two particles which are used to compute
206 the rotation axis of the SRB. The default is None, meaning that the rotation axis is random.
207 \note If you set the chain parameters, will NOT create an SRB from all of them together,
208 but rather in groups made from the outermost list.
214 if chain_min_length
is None and chain_max_length
is None:
218 print(
'WARNING: No hierarchies were passed to create_super_rigid_body()')
222 if not hasattr(srb_parts,
'__iter__'):
223 raise Exception(
"You tried to make a chain without a list!")
225 warn_about_slices=
False)
for h
in srb_parts]
228 if chain_min_length
is None and chain_max_length
is None:
229 mv = self._setup_srb(srb_groups,max_trans,max_rot,axis)
231 mv.set_was_used(
True)
232 srb_movers.append(mv)
233 elif chain_min_length
is not None and chain_max_length
is not None:
235 mv = self._setup_srb(hs,max_trans,max_rot,axis)
237 mv.set_was_used(
True)
238 srb_movers.append(mv)
240 raise Exception(
"DegreesOfFreedom: SetupSuperRigidBody: if you want chain, specify min AND max")
241 self.movers += srb_movers
243 if len(srb_movers)>1:
244 for n,mv
in enumerate(srb_movers):
245 mv.set_name(name+
'_'+str(n))
247 srb_movers[0].set_name(name)
250 def _setup_srb(self,hiers,max_trans,max_rot,axis):
257 self.movers_particles_map[srbm]=[]
260 for xyz
in super_rigid_xyzs:
261 srbm.add_xyz_particle(xyz)
263 for rb
in super_rigid_rbs:
264 srbm.add_rigid_body_particle(rb)
276 """Create a chain of flexible beads
277 @param flex_parts Can be one of the following inputs:
278 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
279 Must be uniform input, however. No mixing object types.
280 @param max_trans Maximum flexible bead translation
281 @param resolution Only used if you pass PMI objects. Probably you want 'all'.
288 if not hiers
or len(hiers)==0:
289 print(
'WARNING: No hierarchies were passed to create_flexible_beads()')
295 raise Exception(
"Cannot create flexible beads from members of rigid body")
296 self.flexible_beads.append(h)
298 fb_movers.append(fbmv)
299 fbmv.set_was_used(
True)
300 self.fb_movers.append(fbmv)
303 self.movers += fb_movers
310 """Create MC normal mover for nuisance particles.
311 We will add an easier interface to add all of them from a PMI restraint
312 @param nuisance_p The Nuisance particle (an ISD::Scale)
313 @param step_size The maximum step size for Monte Carlo
314 @param name The name of the mover, useful for better output reading.
321 mv.set_was_used(
True)
322 self.nuisances.append(nuisance_p)
323 self.movers.append(mv)
328 """Setup particles for MD simulation. Returns all particles, just
329 pass this to molecular_dynamics_sample_objects in ReplicaExchange0.
330 @param hspec Can be one of the following inputs:
331 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
332 Must be uniform input, however. No mixing object types.
338 mdl = hiers[0].get_model()
343 IMP.core.XYZ(mdl,p.get_index()).set_coordinates_are_optimized(
True)
344 mdl.add_attribute(vxkey,p.get_index(),0.0)
345 mdl.add_attribute(vykey,p.get_index(),0.0)
346 mdl.add_attribute(vzkey,p.get_index(),0.0)
356 """Create a symmetry constraint. Checks:
357 same number of particles
358 disable ANY movers involving symmetry copies
359 (later may support moving them WITH references,
360 but requires code to propagate constraint)
361 @param references Can be one of the following inputs:
362 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them
363 @param clones Same format as references
364 @param transform The transform that moves a clone onto a reference
365 IMP.algebra.Transformation3D
366 @param resolution Only used if you pass PMI objects.
367 If you have a multires system, assuming each are rigid
368 bodies you probably only need one resolution.
369 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
388 for ref,clone
in zip(ref_rbs,clones_rbs):
391 for ref,clone
in zip(ref_beads,clones_beads):
401 if type==
"RIGID_BODY":
403 p.set_name(
"RigidBody_Symmetry")
405 for cp
in [(10,0,0),(0,10,0),(0,0,10)]:
410 self.rigid_bodies.append(rb)
411 rb.set_coordinates_are_optimized(
True)
415 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
416 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
417 print(
'Created rigid body symmetry restraint')
418 self.movers_particles_map[rb_mover_tr]=[]
419 self.movers_particles_map[rb_mover_rt]=[]
420 self.movers_rb_map[rb_mover_tr]=[rb]
421 self.movers_rb_map[rb_mover_rt]=[rb]
425 self.movers.append(rb_mover_tr)
426 self.movers.append(rb_mover_rt)
427 self._rb2mov[rb] = [rb_mover_tr,rb_mover_rt]
431 self.mdl,[p.get_particle().
get_index()
for p
in clones_rbs+clones_beads])
433 self.mdl.add_score_state(c)
434 print(
'Created symmetry restraint for',len(ref_rbs),
'rigid bodies and',
435 len(ref_beads),
'flexible beads')
451 return 'DegreesOfFreedom: ' + \
452 "\n".join(repr(m)
for m
in self.movers)
455 '''Set up MC run with just flexible beads.
456 Optimization works much better when restraints
457 are already set up.'''
458 pts = IMP.pmi.tools.ParticleToSampleList()
460 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Flexible_Bead_" + str(n))
461 if len(pts.get_particles_to_sample()) > 0:
463 print(
"optimize_flexible_beads: optimizing %i flexible beads" % len(self.
get_flexible_beads()))
466 print(
"optimize_flexible_beads: no particle to optimize")
469 """Returns Enabled movers"""
470 if self.disabled_movers:
471 filtered_mover_list=[]
472 for mv
in self.movers:
473 if not mv
in self.disabled_movers:
474 filtered_mover_list.append(mv)
475 return filtered_mover_list
480 """Return all movers corresponding to individual beads"""
481 return self.fb_movers
484 """Return list of rigid body objects"""
485 return self.rigid_bodies
488 """Return all flexible beads, including nonrigid members of rigid bodies"""
489 return self.flexible_beads
492 """Fix the position of the particles by disabling the corresponding movers
493 @param objects Can be one of the following inputs:
494 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
495 Must be uniform input, however. No mixing object types.
496 @param mover_types further filter the mover type that will be disabled, it can be a list of IMP.core.RigidBodyMover,
497 IMP.core.BallMover etc etc if one wants to fix the corresponding rigid body, or the floppy bodies.
498 An empty mover_types list is interpreted as all possible movers.
499 It returns the list of fixed xyz particles (ie, floppy bodies/beads) and rigid bodies
500 whose movers were disabled
503 pmi_resolution=
'all',
508 if mover_types
is None: mover_types=[]
511 for mv, ps
in self.movers_particles_map.items():
513 if p
in inv_map: inv_map[p].append(mv)
514 else: inv_map[p]=[mv]
516 for h
in hierarchies:
518 for mv
in inv_map[h]:
519 if (type(mv)
in mover_types
or not mover_types):
521 if mv
in self.movers_rb_map:
522 fixed_rb|=set(self.movers_rb_map[mv])
523 if mv
in self.movers_xyz_map:
524 fixed_xyz|=set(self.movers_xyz_map[mv])
525 print(
"Fixing %s movers" %(str(len(list(tmp_set)))))
526 self.disabled_movers+=list(tmp_set)
527 return list(fixed_xyz),list(fixed_rb)
530 """Reenable all movers: previously fixed particles will be released"""
531 self.disabled_movers=[]
534 """Extract the nuisances from get_particles_to_sample()"""
536 pslist = r.get_particles_to_sample()
538 raise Exception(
"dof.get_nuisances_from_restraint(): the passed object does not have a "
539 "get_particles_to_sample() function")
542 if len(pslist[name])==3:
543 ps,maxtrans,is_sampled = pslist[name]
545 ps,maxtrans = pslist[name]
def optimize_flexible_beads
Set up MC run with just flexible beads.
A class to simplify create of constraints and movers for an IMP Hierarchy.
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)