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=[]
82 def _get_nonrigid_hiers(self, nonrigid_parts, rigid_hiers, resolution):
83 """Get Hierarchy objects for nonrigid parts. Make sure that they are
84 a subset of the rigid body Hierarchies."""
85 if not nonrigid_parts:
87 nr_hiers = IMP.pmi.tools.input_adaptor(nonrigid_parts, resolution,
90 rb_idxs = set(h.get_particle_index()
for h
in rigid_hiers)
93 if p.get_index()
not in rb_idxs:
95 "You tried to create nonrigid members from "
96 "particles that aren't in the RigidBody!")
104 nonrigid_max_trans = 4.0,
107 """Create rigid body constraint and mover
108 @param rigid_parts Can be one of the following inputs:
109 IMP Hierarchy, PMI System/State/Molecule/TempResidue, a list/set
110 (of list/set) of them or a RigidBody object.
111 Must be uniform input, however. No mixing object types.
112 @param nonrigid_parts Same input format as rigid_parts.
113 Must be a subset of rigid_parts particles.
114 @param max_trans Maximum rigid body translation
115 @param max_rot Maximum rigid body rotation
116 @param nonrigid_max_trans Maximum step for the nonrigid (bead) particles
117 @param resolution Only used if you pass PMI objects. Probably you
119 @param name Rigid body name (if None, use IMP default)
120 @eturn (rb_movers,rb_object)
121 @note If you want all resolutions, pass PMI objects because this
122 function will get them all. Alternatively you can do your
123 selection elsewhere and just pass hierarchies.
132 print(
"WARNING: Rigid Body Already Setup")
140 hiers = IMP.pmi.tools.input_adaptor(rigid_parts,
145 print(
"WARNING: No hierarchies were passed to create_rigid_body()")
150 nr_hiers = self._get_nonrigid_hiers(nonrigid_parts, hiers, resolution)
153 model=hiers[0].get_model()
166 rb.add_member(h.get_particle())
168 self.rigid_bodies.append(rb)
169 rb.set_coordinates_are_optimized(
True)
174 rb_mover.set_name(name)
175 rb_movers.append(rb_mover)
176 self.movers_particles_map[rb_mover]=[]
177 self.movers_rb_map[rb_mover]=[rb]
178 rb_mover.set_was_used(
True)
185 self.flexible_beads.append(h)
187 rb.set_is_rigid_member(p.get_index(),
False)
189 p.set_is_optimized(fk,
True)
193 self.fb_movers.append(fbmv)
196 fbmv.set_was_used(
True)
197 rb_movers.append(fbmv)
199 self.movers += rb_movers
200 self._rb2mov[rb] = rb_movers
205 """Create crankshaft moves from a set of SUPER rigid body mover from one molecule.
206 See http://scfbm.biomedcentral.com/articles/10.1186/1751-0473-3-12
208 hiers=IMP.pmi.tools.input_adaptor(molecule,resolution,flatten=
True)
210 for length
in lengths:
211 for n
in range(len(hiers)-length):
212 hs=hiers[n+1:n+length]
214 self.
create_super_rigid_body(hs, max_trans=0.0,max_rot=0.05, axis=(hiers[n].get_particle(),hiers[n+length].get_particle()))
227 chain_min_length=
None,
228 chain_max_length=
None,
232 """Create SUPER rigid body mover from one or more hierarchies.
234 Can also create chain of SRBs. If you don't pass chain min/max,
235 it'll treat everything you pass as ONE rigid body.
236 If you DO pass chain min/max, it'll expect srb_parts is a list
237 and break it into bits.
238 @param srb_parts Can be one of the following inputs:
239 IMP Hierarchy, PMI System/State/Molecule/TempResidue,
240 or a list/set (of list/set) of them.
241 Must be uniform input, however. No mixing object types.
242 @param max_trans Maximum super rigid body translation
243 @param max_rot Maximum super rigid body rotation
244 @param chain_min_length Create a CHAIN of super rigid bodies -
245 must provide list; this parameter is the minimum chain length.
246 @param chain_max_length Maximum chain length
247 @param resolution Only used if you pass PMI objects. Probably you
249 @param name The name of the SRB (hard to assign a good one
251 @param axis A tuple containing two particles which are used to
252 compute the rotation axis of the SRB. The default is None,
253 meaning that the rotation axis is random.
255 @note If you set the chain parameters, will NOT create an SRB from
256 all of them together, but rather in groups made from the
263 if chain_min_length
is None and chain_max_length
is None:
265 h = IMP.pmi.tools.input_adaptor(srb_parts,resolution,flatten=
True)
267 print(
'WARNING: No hierarchies were passed to create_super_rigid_body()')
271 if not hasattr(srb_parts,
'__iter__'):
272 raise Exception(
"You tried to make a chain without a list!")
273 srb_groups = [IMP.pmi.tools.input_adaptor(h,resolution,flatten=
True,
274 warn_about_slices=
False)
for h
in srb_parts]
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:
283 for hs
in IMP.pmi.tools.sublist_iterator(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)
289 raise Exception(
"DegreesOfFreedom: SetupSuperRigidBody: if you want chain, specify min AND max")
290 self.movers += srb_movers
292 if len(srb_movers)>1:
293 for n,mv
in enumerate(srb_movers):
294 mv.set_name(name+
'_'+str(n))
296 srb_movers[0].set_name(name)
299 def _setup_srb(self,hiers,max_trans,max_rot,axis):
304 super_rigid_rbs,super_rigid_xyzs = IMP.pmi.tools.get_rbs_and_beads(hiers)
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
337 hiers = IMP.pmi.tools.input_adaptor(flex_parts,
340 if not hiers
or len(hiers)==0:
341 print(
'WARNING: No hierarchies were passed to create_flexible_beads()')
347 raise Exception(
"Cannot create flexible beads from members of rigid body")
348 self.flexible_beads.append(h)
350 fb_movers.append(fbmv)
351 fbmv.set_was_used(
True)
352 self.fb_movers.append(fbmv)
355 self.movers += fb_movers
362 """Create MC normal mover for nuisance particles.
363 We will add an easier interface to add all of them from a PMI restraint
364 @param nuisance_p The Nuisance particle (an ISD::Scale)
365 @param step_size The maximum step size for Monte Carlo
366 @param name The name of the mover, useful for better output reading.
373 mv.set_was_used(
True)
374 self.nuisances.append(nuisance_p)
375 self.movers.append(mv)
380 """Setup particles for MD simulation. Returns all particles, just
381 pass this to molecular_dynamics_sample_objects in ReplicaExchange0.
382 @param hspec Can be one of the following inputs:
383 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
384 Must be uniform input, however. No mixing object types.
389 hiers = IMP.pmi.tools.input_adaptor(hspec,flatten=
True)
390 model = hiers[0].get_model()
395 IMP.core.XYZ(model,p.get_index()).set_coordinates_are_optimized(
True)
396 model.add_attribute(vxkey,p.get_index(),0.0)
397 model.add_attribute(vykey,p.get_index(),0.0)
398 model.add_attribute(vzkey,p.get_index(),0.0)
408 """Create a symmetry constraint. Checks:
409 same number of particles
410 disable ANY movers involving symmetry copies
411 (later may support moving them WITH references,
412 but requires code to propagate constraint)
413 @param references Can be one of the following inputs:
414 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them
415 @param clones Same format as references
416 @param transform The transform that moves a clone onto a reference
417 IMP.algebra.Transformation3D
418 @param resolution Only used if you pass PMI objects.
419 If you have a multires system, assuming each are rigid
420 bodies you probably only need one resolution.
421 @param type of symmetry. Implemented = AXIAL, RIGID_BODY
425 href = IMP.pmi.tools.input_adaptor(references,resolution,flatten=
True)
426 hclones = IMP.pmi.tools.input_adaptor(clones,resolution,flatten=
True)
428 ref_rbs,ref_beads = IMP.pmi.tools.get_rbs_and_beads(href)
429 clones_rbs,clones_beads = IMP.pmi.tools.get_rbs_and_beads(hclones)
440 for ref,clone
in zip(ref_rbs,clones_rbs):
443 for ref,clone
in zip(ref_beads,clones_beads):
453 if type==
"RIGID_BODY":
455 p.set_name(
"RigidBody_Symmetry")
457 for cp
in [(10,0,0),(0,10,0),(0,0,10)]:
462 self.rigid_bodies.append(rb)
463 rb.set_coordinates_are_optimized(
True)
467 rb_mover_tr.set_name(
"RigidBody_Symmetry_Mover_Translate")
468 rb_mover_rt.set_name(
"RigidBody_Symmetry_Mover_Rotate")
469 print(
'Created rigid body symmetry restraint')
470 self.movers_particles_map[rb_mover_tr]=[]
471 self.movers_particles_map[rb_mover_rt]=[]
472 self.movers_rb_map[rb_mover_tr]=[rb]
473 self.movers_rb_map[rb_mover_rt]=[rb]
477 self.movers.append(rb_mover_tr)
478 self.movers.append(rb_mover_rt)
479 self._rb2mov[rb] = [rb_mover_tr,rb_mover_rt]
483 self.model,[p.get_particle().
get_index()
for p
in clones_rbs+clones_beads])
485 self.model.add_score_state(c)
486 print(
'Created symmetry restraint for',len(ref_rbs),
'rigid bodies and',
487 len(ref_beads),
'flexible beads')
503 return 'DegreesOfFreedom: ' + \
504 "\n".join(repr(m)
for m
in self.movers)
507 '''Set up MC run with just flexible beads.
508 Optimization works much better when restraints
509 are already set up.'''
510 pts = IMP.pmi.tools.ParticleToSampleList()
512 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Flexible_Bead_" + str(n))
513 if len(pts.get_particles_to_sample()) > 0:
515 print(
"optimize_flexible_beads: optimizing %i flexible beads" % len(self.
get_flexible_beads()))
518 print(
"optimize_flexible_beads: no particle to optimize")
521 """Returns Enabled movers"""
522 if self.disabled_movers:
523 filtered_mover_list=[]
524 for mv
in self.movers:
525 if not mv
in self.disabled_movers:
526 filtered_mover_list.append(mv)
527 return filtered_mover_list
532 """Return all movers corresponding to individual beads"""
533 return self.fb_movers
536 """Return list of rigid body objects"""
537 return self.rigid_bodies
540 """Return all flexible beads, including nonrigid members of rigid bodies"""
541 return self.flexible_beads
544 """Fix the position of the particles by disabling the corresponding movers
545 @param objects Can be one of the following inputs:
546 IMP Hierarchy, PMI System/State/Molecule/TempResidue, or a list/set (of list/set) of them.
547 Must be uniform input, however. No mixing object types.
548 @param mover_types further filter the mover type that will be disabled, it can be a list of IMP.core.RigidBodyMover,
549 IMP.core.BallMover etc etc if one wants to fix the corresponding rigid body, or the floppy bodies.
550 An empty mover_types list is interpreted as all possible movers.
551 It returns the list of fixed xyz particles (ie, floppy bodies/beads) and rigid bodies
552 whose movers were disabled
554 hierarchies = IMP.pmi.tools.input_adaptor(objects,
555 pmi_resolution=
'all',
560 if mover_types
is None: mover_types=[]
563 for mv, ps
in self.movers_particles_map.items():
565 if p
in inv_map: inv_map[p].append(mv)
566 else: inv_map[p]=[mv]
568 for h
in hierarchies:
570 for mv
in inv_map[h]:
571 if (type(mv)
in mover_types
or not mover_types):
573 if mv
in self.movers_rb_map:
574 fixed_rb|=set(self.movers_rb_map[mv])
575 if mv
in self.movers_xyz_map:
576 fixed_xyz|=set(self.movers_xyz_map[mv])
577 print(
"Fixing %s movers" %(str(len(list(tmp_set)))))
578 self.disabled_movers+=list(tmp_set)
579 return list(fixed_xyz),list(fixed_rb)
582 """Reenable all movers: previously fixed particles will be released"""
583 self.disabled_movers=[]
586 """Extract the nuisances from get_particles_to_sample()"""
588 pslist = r.get_particles_to_sample()
590 raise Exception(
"dof.get_nuisances_from_restraint(): the passed object does not have a "
591 "get_particles_to_sample() function")
594 if len(pslist[name])==3:
595 ps,maxtrans,is_sampled = pslist[name]
597 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.
def deprecated_method
Python decorator to mark a method as deprecated.
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)