1 """@namespace IMP.pmi.samplers
2 Sampling of the system.
8 class _SerialReplicaExchange(object):
9 """Dummy replica exchange class used in non-MPI builds.
10 It should act similarly to IMP.mpi.ReplicaExchange on a single processor.
14 def get_number_of_replicas(self):
16 def create_temperatures(self, tmin, tmax, nrep):
18 def get_my_index(self):
20 def set_my_parameter(self, key, val):
21 self.__params[key] = val
22 def get_my_parameter(self, key):
23 return self.__params[key]
24 def get_friend_index(self, step):
26 def get_friend_parameter(self, key, findex):
27 return self.get_my_parameter(key)
28 def do_exchange(self, myscore, fscore, findex):
32 class MonteCarlo(object):
41 def __init__(self, m, objects, temp, filterbyname=None):
43 check that the objects containts get_particles_to_sample methods
44 and the particle type is supported
45 list of particles to sample self.losp
54 self.simulated_annealing =
False
55 self.selfadaptive =
False
66 ob.get_particles_to_sample()
68 print "MonteCarlo: object ", ob,
" doesn't have get_particles_to_sample() method"
70 pts = ob.get_particles_to_sample()
73 if "Rigid_Bodies" in k:
74 mvs = self.get_rigid_body_movers(
84 mvs = self.get_super_rigid_body_movers(
92 if "Floppy_Bodies" in k:
93 mvs = self.get_floppy_body_movers(pts[k][0], pts[k][1])
99 mvs = self.get_X_movers(pts[k][0], pts[k][1])
105 if not self.isd_available:
106 print "MonteCarlo: isd module needed to use nuisances"
108 mvs = self.get_nuisance_movers(pts[k][0], pts[k][1])
114 if not self.isd_available:
115 print "MonteCarlo: isd module needed to use weights"
117 mvs = self.get_weight_movers(pts[k][0], pts[k][1])
126 self.mc.set_return_best(
False)
127 self.mc.set_kt(self.temp)
128 self.mc.add_mover(self.smv)
130 def set_kt(self, temp):
137 def set_scoring_function(self, objectlist):
139 for ob
in objectlist:
140 rs.add_restraint(ob.get_restraint())
142 self.mc.set_scoring_function(sf)
144 def set_simulated_annealing(
150 self.simulated_annealing =
True
151 self.tempmin = min_temp
152 self.tempmax = max_temp
153 self.timemin = min_temp_time
154 self.timemax = max_temp_time
156 def set_self_adaptive(self, isselfadaptive=True):
157 self.selfadaptive = isselfadaptive
159 def get_nuisance_movers_parameters(self):
160 '''returns a dictionary with the mover parameters
161 for nuisance parameters'''
163 for i
in range(self.get_number_of_movers()):
164 mv = self.smv.get_mover(i)
166 if "Nuisances" in name:
167 stepsize = IMP.core.NormalMover.get_from(mv).get_sigma()
168 output[name] = stepsize
171 def get_number_of_movers(self):
172 return len(self.smv.get_movers())
174 def get_particle_types():
177 def optimize(self, nstep):
179 self.mc.optimize(nstep * self.get_number_of_movers())
182 if self.simulated_annealing:
183 self.temp = self.temp_simulated_annealing()
184 self.mc.set_kt(self.temp)
187 if self.selfadaptive:
188 for i, mv
in enumerate(self.smv.get_movers()):
191 if "Nuisances" in name:
192 mvacc = mv.get_number_of_accepted()
193 mvprp = mv.get_number_of_proposed()
194 accept = float(mvacc) / float(mvprp)
195 nmv = IMP.core.NormalMover.get_from(mv)
196 stepsize = nmv.get_sigma()
198 if 0.4 > accept
or accept > 0.6:
199 nmv.set_sigma(stepsize * 2 * accept)
202 nmv.set_sigma(stepsize * 2 * accept)
205 nmv.set_sigma(stepsize * 2 * accept)
207 if "Weights" in name:
209 mvacc = mv.get_number_of_accepted()
210 mvprp = mv.get_number_of_proposed()
211 accept = float(mvacc) / float(mvprp)
212 wmv = IMP.isd.WeightMover.get_from(mv)
213 stepsize = wmv.get_radius()
215 if 0.4 > accept
or accept > 0.6:
216 wmv.set_radius(stepsize * 2 * accept)
219 wmv.set_radius(stepsize * 2 * accept)
222 wmv.set_radius(stepsize * 2 * accept)
224 def run(self, *args, **kwargs):
225 IMP.pmi.tools.print_deprecation_warning(
227 "MonteCarlo.optimize")
228 self.optimize(*args, **kwargs)
230 def get_nuisance_movers(self, nuisances, maxstep):
232 for nuisance
in nuisances:
233 print nuisance, maxstep
240 def get_rigid_body_movers(self, rbs, maxtrans, maxrot):
246 def get_super_rigid_body_movers(self, rbs, maxtrans, maxrot):
260 srbm.add_xyz_particle(xyz)
262 srbm.add_rigid_body_particle(rb)
266 def get_floppy_body_movers(self, fbs, maxtrans):
274 fb.set_is_optimized(fk,
True)
284 def get_X_movers(self, fbs, maxtrans):
290 print "particle is part of a rigid body"
297 def get_weight_movers(self, weights, maxstep):
299 for weight
in weights:
300 if(weight.get_number_of_states() > 1):
304 def temp_simulated_annealing(self):
305 if self.nframe % (self.timemin + self.timemax) < self.timemin:
309 temp = self.tempmin + (self.tempmax - self.tempmin) * value
312 def set_label(self, label):
315 def get_frame_number(self):
318 def get_output(self):
321 for i, mv
in enumerate(self.smv.get_movers()):
322 mvname = mv.get_name()
323 mvacc = mv.get_number_of_accepted()
324 mvprp = mv.get_number_of_proposed()
326 mvacr = float(mvacc) / float(mvprp)
329 output[
"MonteCarlo_Acceptance_" +
330 mvname +
"_" + str(i)] = str(mvacr)
331 if "Nuisances" in mvname:
332 output[
"MonteCarlo_StepSize_" + mvname +
"_" +
333 str(i)] = str(IMP.core.NormalMover.get_from(mv).get_sigma())
334 if "Weights" in mvname:
335 output[
"MonteCarlo_StepSize_" + mvname +
"_" +
336 str(i)] = str(IMP.isd.WeightMover.get_from(mv).get_radius())
337 output[
"MonteCarlo_Temperature"] = str(self.mc.get_kt())
338 output[
"MonteCarlo_Nframe"] = str(self.nframe)
342 class MolecularDynamics(object):
343 def __init__(self,m,objects,kt,gamma=0.01,maximum_time_step=1.0):
347 to_sample+=obj.get_particles_to_sample()[
'Floppy_Bodies_SimplifiedModel'][0]
352 self.md.set_maximum_time_step(maximum_time_step)
353 self.md.add_optimizer_state(self.ltstate)
357 self.ltstate.set_temperature(temp)
358 self.md.assign_velocities(temp)
360 def set_gamma(self,gamma):
361 self.ltstate.set_gamma(gamma)
363 def optimize(self,nsteps):
364 self.md.optimize(nsteps)
366 def get_output(self):
368 output[
"MolecularDynamics_KineticEnergy"]=str(self.md.get_kinetic_energy())
371 class ConjugateGradients(object):
373 def __init__(self, m, objects):
378 def set_label(self, label):
381 def get_frame_number(self):
384 def run(self, nstep):
386 self.cg.optimize(nstep)
388 def set_scoring_function(self, objectlist):
390 for ob
in objectlist:
391 rs.add_restraint(ob.get_restraint())
393 self.cg.set_scoring_function(sf)
395 def get_output(self):
398 output[
"ConjugatedGradients_Nframe"] = str(self.nframe)
402 class ReplicaExchange(object):
411 replica_exchange_object=
None):
413 samplerobjects can be a list of MonteCarlo or MolecularDynamics
418 self.samplerobjects = samplerobjects
420 self.TEMPMIN_ = tempmin
421 self.TEMPMAX_ = tempmax
423 if replica_exchange_object
is None:
429 self.rem = _SerialReplicaExchange()
433 print 'got existing rex object'
434 self.rem = replica_exchange_object
437 nproc = self.rem.get_number_of_replicas()
439 if nproc % 2 != 0
and test ==
False:
440 raise Exception,
"number of replicas has to be even. set test=True to run with odd number of replicas."
442 temp = self.rem.create_temperatures(
447 self.temperatures = temp
449 myindex = self.rem.get_my_index()
451 self.rem.set_my_parameter(
"temp", [self.temperatures[myindex]])
452 for so
in self.samplerobjects:
453 so.set_kt(self.temperatures[myindex])
459 def get_temperatures(self):
460 return self.temperatures
462 def get_my_temp(self):
463 return self.rem.get_my_parameter(
"temp")[0]
465 def get_my_index(self):
466 return self.rem.get_my_index()
468 def swap_temp(self, nframe, score=None):
470 score = self.m.evaluate(
False)
472 myindex = self.rem.get_my_index()
473 mytemp = self.rem.get_my_parameter(
"temp")[0]
475 if mytemp == self.TEMPMIN_:
478 if mytemp == self.TEMPMAX_:
482 myscore = score / mytemp
485 findex = self.rem.get_friend_index(nframe)
486 ftemp = self.rem.get_friend_parameter(
"temp", findex)[0]
488 fscore = score / ftemp
491 flag = self.rem.do_exchange(myscore, fscore, findex)
496 for so
in self.samplerobjects:
500 def get_output(self):
503 if self.nattempts != 0:
504 output[
"ReplicaExchange_SwapSuccessRatio"] = str(
505 float(self.nsuccess) / self.nattempts)
506 output[
"ReplicaExchange_MinTempFrequency"] = str(
507 float(self.nmintemp) / self.nattempts)
508 output[
"ReplicaExchange_MaxTempFrequency"] = str(
509 float(self.nmaxtemp) / self.nattempts)
511 output[
"ReplicaExchange_SwapSuccessRatio"] = str(0)
512 output[
"ReplicaExchange_MinTempFrequency"] = str(0)
513 output[
"ReplicaExchange_MaxTempFrequency"] = str(0)
514 output[
"ReplicaExchange_CurrentTemp"] = str(self.get_my_temp())
518 class PyMCMover(object):
521 def __init__(self, representation, mcchild, n_mc_steps):
526 self.rbs = representation.get_rigid_bodies()
529 self.n_mc_steps = n_mc_steps
531 def store_move(self):
534 for copy
in self.rbs:
537 crd.append(rb.get_reference_frame())
538 self.oldcoords.append(crd)
540 def propose_move(self, prob):
541 self.mc.run(self.n_mc_steps)
543 def reset_move(self):
545 for copy, crd
in zip(self.rbs, self.oldcoords):
546 for rb, ref
in zip(copy, crd):
547 rb.set_reference_frame(ref)
549 def get_number_of_steps(self):
550 return self.n_mc_steps
552 def set_number_of_steps(self, nsteps):
553 self.n_mc_steps = nsteps
558 def __init__(self, model):
563 self.restraints =
None
564 self.first_call =
True
567 def add_mover(self, mv):
570 def set_kt(self, kT):
573 def set_return_best(self, thing):
576 def set_move_probability(self, thing):
579 def get_energy(self):
581 pot = sum([r.evaluate(
False)
for r
in self.restraints])
583 pot = self.m.evaluate(
False)
586 def metropolis(self, old, new):
588 print ": old %f new %f deltaE %f new_epot: %f" % (old, new, deltaE,
595 return exp(-deltaE / kT) > random.uniform(0, 1)
597 def optimize(self, nsteps):
600 print "=== new MC call"
604 self.first_call =
False
605 for i
in xrange(nsteps):
606 print "MC step %d " % i,
608 old = self.get_energy()
610 self.mv.propose_move(1)
612 new = self.get_energy()
613 if self.metropolis(old, new):
623 def get_number_of_forward_steps(self):
626 def set_restraints(self, restraints):
627 self.restraints = restraints
629 def set_scoring_function(self, objects):
633 rs.add_restraint(ob.get_restraint())
634 self.set_restraints([rs])
636 def get_output(self):
639 output[
"PyMC_Temperature"] = str(self.kT)
640 output[
"PyMC_Nframe"] = str(self.nframe)
A class to implement Hamiltonian Replica Exchange.
Maintains temperature during molecular dynamics.
Object used to hold a set of restraints.
Modify the transformation of a rigid body.
Simple conjugate gradients optimizer.
Modify a set of continuous variables by perturbing them within a ball.
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
Simple molecular dynamics optimizer.
Code that uses the MPI parallel library.
Modify the transformation of a rigid body.
Modify a set of continuous variables using a normal distribution.
Basic functionality that is expected to be used by a wide variety of IMP users.
static const FloatKeys & get_xyz_keys()
Get a vector containing the keys for x,y,z.
Applies a list of movers one at a time.
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...