class lbfgs_gradient(object): def __init__(self, atoms, restraints): self.restraints = restraints self.opt = LBFGS(atoms=atoms) def step(self): pos = self.opt.atoms.get_positions() sites_cart = flex.vec3_double(pos) e, g = self.restraints.target_and_gradients(sites_cart) forces = np.array(g) * -1 self.opt.step(forces) def write(self, file): write(file, self.opt.atoms) def run(self, nstep): for i in range(nstep): self.step()
class minimizer_ase(object): def __init__(self, calculator, params, max_iterations, geometry_rmsd_manager): self.params = params self.max_iterations = max_iterations self.calculator = calculator self.geometry_rmsd_manager = geometry_rmsd_manager self.ase_atoms = calculator.ase_atoms self.ase_atoms.set_positions(flex.vec3_double(self.calculator.x)) self.opt = LBFGS(atoms=self.ase_atoms) self.number_of_function_and_gradients_evaluations = 0 self.b_rmsd = self._get_bond_rmsd( sites_cart=flex.vec3_double(self.calculator.x)) print(" step: %3d bond rmsd: %8.6f" % (self.number_of_function_and_gradients_evaluations, self.b_rmsd)) self.run(nstep=max_iterations) # Syncing and cross-checking begin e = 1.e-4 assert approx_equal(self.ase_atoms.get_positions(), self.opt.atoms.get_positions(), e) self.calculator.update(x=self.opt.atoms.get_positions()) assert approx_equal(self.calculator.x, self.opt.atoms.get_positions(), e) if (params.refine.mode == "refine"): assert approx_equal( flex.vec3_double(self.calculator.x), self.calculator.fmodel.xray_structure.sites_cart(), e) else: assert approx_equal(flex.vec3_double(self.calculator.x), self.calculator.xray_structure.sites_cart(), e) b_rmsd = self._get_bond_rmsd( sites_cart=flex.vec3_double(self.calculator.x)) assert approx_equal(self.b_rmsd, b_rmsd, e) # Syncing and cross-checking end def _get_bond_rmsd(self, sites_cart): b_mean = None if (self.geometry_rmsd_manager is not None): energies_sites = \ self.geometry_rmsd_manager.geometry.energies_sites( sites_cart = sites_cart.select(s), compute_gradients = False) b_mean = energies_sites.bond_deviations()[2] return b_mean def step(self): sites_cart = flex.vec3_double(self.opt.atoms.get_positions()) t, g = self.calculator.target_and_gradients(x=sites_cart) forces = numpy.array(g) * (-1) self.opt.step(forces) self.number_of_function_and_gradients_evaluations += 1 self.calculator.update(x=self.opt.atoms.get_positions()) # self.b_rmsd = self._get_bond_rmsd( sites_cart=flex.vec3_double(self.opt.atoms.get_positions())) print(" step: %3d bond rmsd: %8.6f" % (self.number_of_function_and_gradients_evaluations, self.b_rmsd)) if (self.params.refine.mode == "refine" and self.b_rmsd > self.params.refine.max_bond_rmsd and self.number_of_function_and_gradients_evaluations > 20): return False # return True def run(self, nstep): for i in range(nstep): v = self.step() if (not v): return