def retrieve(self): ff = FFEvaluate(self.molecule, self._parameters) results = [] for iframe in range(self.molecule.numFrames): self.molecule.frame = iframe directory = os.path.join(self.directory, '%05d' % iframe) os.makedirs(directory, exist_ok=True) pickleFile = os.path.join(directory, 'data.pkl') if self._completed(directory): with open(pickleFile, 'rb') as fd: result = pickle.load(fd) logger.info('Loading QM data from %s' % pickleFile) else: result = QMResult() result.errored = False result.coords = self.molecule.coords[:, :, iframe:iframe + 1].copy() if self.optimize: opt = nlopt.opt(nlopt.LN_COBYLA, result.coords.size) opt.set_min_objective(lambda x, _: ff.calculateEnergies(x.reshape((-1, 3)))['total']) if self.restrained_dihedrals is not None: for dihedral in self.restrained_dihedrals: indices = dihedral.copy() ref_angle = dihedralAngle(self.molecule.coords[indices, :, iframe]) def constraint(x, _): coords = x.reshape((-1, 3)) angle = dihedralAngle(coords[indices]) return np.sin(.5*(angle - ref_angle)) opt.add_equality_constraint(constraint) opt.set_xtol_abs(1e-3) # Similar to Psi4 default opt.set_maxeval(1000*opt.get_dimension()) opt.set_initial_step(1e-3) result.coords = opt.optimize(result.coords.ravel()).reshape((-1, 3, 1)) logger.info('Optimization status: %d' % opt.last_optimize_result()) result.energy = ff.calculateEnergies(result.coords[:, :, 0])['total'] result.dipole = getDipole(self.molecule) if self.optimize: assert opt.last_optimum_value() == result.energy # A self-consistency test # Compute ESP values if self.esp_points is not None: assert self.molecule.numFrames == 1 result.esp_points = self.esp_points distances = cdist(result.esp_points, result.coords[:, :, 0]) # Angstrom distances *= const.physical_constants['Bohr radius'][0] / const.angstrom # Angstrom --> Bohr result.esp_values = np.dot(np.reciprocal(distances), self.molecule.charge) # Hartree/Bohr with open(pickleFile, 'wb') as fd: pickle.dump(result, fd) results.append(result) return results
def run(self): ff = FFEvaluate(self.molecule) results = [] for iframe in range(self.molecule.numFrames): self.molecule.frame = iframe directory = os.path.join(self.directory, '%05d' % iframe) os.makedirs(directory, exist_ok=True) pickleFile = os.path.join(directory, 'data.pkl') if self._completed(directory): with open(pickleFile, 'rb') as fd: result = pickle.load(fd) logger.info('Loading QM data from %s' % pickleFile) else: result = QMResult() result.errored = False result.coords = self.molecule.coords[:, :, iframe:iframe + 1].copy() if self.optimize: opt = nlopt.opt(nlopt.LN_COBYLA, result.coords.size) opt.set_min_objective(lambda x, _: ff.run(x.reshape((-1, 3)))['total']) if self.restrained_dihedrals is not None: for dihedral in self.restrained_dihedrals: indices = dihedral.copy() ref_angle = np.deg2rad(dihedralAngle(self.molecule.coords[indices, :, iframe])) def constraint(x, _): coords = x.reshape((-1, 3)) angle = np.deg2rad(dihedralAngle(coords[indices])) return np.sin(.5*(angle - ref_angle)) opt.add_equality_constraint(constraint) opt.set_xtol_abs(1e-3) # Similar to Psi4 default opt.set_maxeval(1000*opt.get_dimension()) opt.set_initial_step(1e-3) result.coords = opt.optimize(result.coords.ravel()).reshape((-1, 3, 1)) logger.info('Optimization status: %d' % opt.last_optimize_result()) result.energy = ff.run(result.coords[:, :, 0])['total'] result.dipole = self.molecule.getDipole() if self.optimize: assert opt.last_optimum_value() == result.energy # A self-consistency test # Compute ESP values if self.esp_points is not None: assert self.molecule.numFrames == 1 result.esp_points = self.esp_points distances = cdist(result.esp_points, result.coords[:, :, 0]) # Angstrom distances *= const.physical_constants['Bohr radius'][0] / const.angstrom # Angstrom --> Bohr result.esp_values = np.dot(np.reciprocal(distances), self.molecule.charge) # Hartree/Bohr with open(pickleFile, 'wb') as fd: pickle.dump(result, fd) results.append(result) return results
def retrieve(self): results = [] for iframe in range(self.molecule.numFrames): self.molecule.frame = iframe directory = os.path.join(self.directory, '%05d' % iframe) os.makedirs(directory, exist_ok=True) pickleFile = os.path.join(directory, 'data.pkl') molFile = os.path.join(directory, 'mol.mol2') if self._completed(directory): with open(pickleFile, 'rb') as fd: result = pickle.load(fd) logger.info('Loading data from %s' % pickleFile) else: start = time.clock() result = QMResult() result.errored = False result.coords = self.molecule.coords[:, :, iframe:iframe + 1].copy() if self.optimize: if self.minimizer is None: self.minimizer = CustomEnergyBasedMinimizer( self.molecule, self.calculator) result.coords = self.minimizer.minimize( result.coords, self.restrained_dihedrals).reshape( (-1, 3, 1)) mol = self.molecule.copy() mol.frame = 0 mol.coords = result.coords mol.write(molFile) result.energy = float( self.calculator.calculate(result.coords, self.molecule.element, units='kcalmol')[0]) result.dipole = [0, 0, 0] #if self.optimize: # assert opt.last_optimum_value() == result.energy # A self-consistency test finish = time.clock() result.calculator_time = finish - start if self._verbose: logger.info('Custom calculator calculation time: %f s' % result.calculator_time) with open(pickleFile, 'wb') as fd: pickle.dump(result, fd) results.append(result) return results
def run(self): prmtop = self._get_prmtop() system = prmtop.createSystem() groups = {force.getForceGroup() for force in system.getForces()} if self.optimize: if self.restrained_dihedrals is not None: restraint = openmm.PeriodicTorsionForce() restraint.setForceGroup(max(groups) + 1) for dihedral in self.restrained_dihedrals: restraint.addTorsion(*tuple(map(int, dihedral)), periodicity=1, phase=0, k=-1000 * unit.kilocalorie_per_mole) system.addForce(restraint) simulation = app.Simulation( prmtop.topology, system, openmm.VerletIntegrator(1 * unit.femtosecond), openmm.Platform.getPlatformByName('CPU')) results = [] molecule_copy = self.molecule.copy() for iframe in range(self.molecule.numFrames): self.molecule.frame = iframe molecule_copy.frame = iframe directory = os.path.join(self.directory, '%05d' % iframe) os.makedirs(directory, exist_ok=True) pickleFile = os.path.join(directory, 'data.pkl') if self._completed(directory): with open(pickleFile, 'rb') as fd: results.append(pickle.load(fd)) logger.info('Loading QM data from %s' % pickleFile) continue simulation.context.setPositions( self.molecule.coords[:, :, iframe] * unit.angstrom) if self.optimize: if self.restrained_dihedrals is not None: for i, dihedral in enumerate(self.restrained_dihedrals): ref_angle = dihedralAngle( self.molecule.coords[dihedral, :, iframe]) parameters = restraint.getTorsionParameters(i) parameters[5] = ref_angle * unit.degree restraint.setTorsionParameters(i, *parameters) restraint.updateParametersInContext(simulation.context) simulation.minimizeEnergy(tolerance=0.001 * unit.kilocalorie_per_mole) state = simulation.context.getState(getEnergy=True, getPositions=True, groups=groups) result = QMResult() result.errored = False result.energy = state.getPotentialEnergy().value_in_unit( unit.kilocalorie_per_mole) result.coords = state.getPositions(asNumpy=True).value_in_unit( unit.angstrom).reshape((-1, 3, 1)) result.dipole = self.molecule.getDipole() if self.esp_points is not None: assert self.molecule.numFrames == 1 result.esp_points = self.esp_points distances = cdist(result.esp_points, result.coords[:, :, 0]) # Angstrom distances *= const.physical_constants['Bohr radius'][ 0] / const.angstrom # Angstrom --> Bohr result.esp_values = np.dot( np.reciprocal(distances), self.molecule.charge) # Hartree/Bohr results.append(result) with open(pickleFile, 'wb') as fd: pickle.dump(result, fd) self.molecule.write(os.path.join( directory, 'mol-init.mol2')) # Write an optimiz molecule_copy.coords[:, :, iframe] = result.coords[:, :, 0] molecule_copy.write(os.path.join(directory, 'mol.mol2')) # Write an optimiz return results
def _readOutput(self, directory): result = QMResult() result.completed = True xyzFile = os.path.join(directory, 'psi4out.xyz') if os.path.exists(xyzFile): with open(xyzFile) as f: result.energy = float(f.readline().split()[1]) # Read the 2nd number on the 1st line result.energy *= const.physical_constants['Hartree energy'][0]/(const.kilo*const.calorie/const.Avogadro) # Hartree to kcal/mol result.coords = np.loadtxt(xyzFile, skiprows=2, usecols=(1, 2, 3)) result.coords = np.atleast_3d(result.coords) # TODO get rid of this else: result.errored = True if self.esp_points is not None: espFile = os.path.join(directory, 'grid_esp.dat') if os.path.exists(espFile): result.esp_points = self.esp_points result.esp_values = np.loadtxt(espFile) result.esp_values *= const.angstrom/const.physical_constants['Bohr radius'][0] # 1/Bohr to 1/Angstrom else: result.errored = True outFile = os.path.join(directory, 'psi4.out') if os.path.exists(outFile): with open(outFile) as f: lines = f.readlines() for i in range(len(lines)): if "Mulliken Charges: (a.u.)" in lines[i]: result.mulliken = [] for j in range(self._natoms): s = lines[i + 2 + j].split() result.mulliken.append(float(s[5])) if "Dipole Moment: (Debye)" in lines[i]: s = lines[i + 1].split() result.dipole = [float(s[1]), float(s[3]), float(s[5]), float(s[7])] if " Traceless Quadrupole Moment: (Debye Ang)" in lines[i]: s1, s2 = lines[i + 1].split(), lines[i + 2].split() result.quadrupole = [float(s1[1]), float(s1[3]), float(s1[5]), float(s2[1]), float(s2[3]), float(s2[5])] else: result.errored = True return result
def _readOutput(self, directory): result = QMResult() with open(os.path.join(directory, 'g09.out')) as f: fl = f.readlines() try: data = {} for i in range(len(fl)): if "Dipole moment (field-independent basis, Debye):" in fl[i]: s = fl[i + 1].split() data['dipole'] = [ float(s[1]), float(s[3]), float(s[5]), float(s[7]) ] if "Traceless Quadrupole moment (field-independent basis, Debye-Ang):" in fl[ i]: s1 = fl[i + 1].split() s2 = fl[i + 2].split() data['quadrupole'] = [ float(s1[1]), float(s1[3]), float(s1[5]), float(s2[1]), float(s2[3]), float(s2[5]) ] if "Mulliken atomic charges:" in fl[ i] or "Mulliken charges:" in fl[i]: data['mulliken'] = [] for j in range(self._natoms): data['mulliken'].append(float(fl[i + 2 + j].split()[2])) for l in fl: if "SCF Done: E(RHF) = " in l: ff = l.split() data['energy'] = float(ff[4]) if "SCF Done: E(RB3LYP) = " in l: ff = l.split() data['energy'] = float(ff[4]) i = 0 while i < len(fl): if "Number Number Type X Y Z" in fl[ i]: i += 2 data['coords'] = np.zeros((self._natoms, 3)) for j in range(self._natoms): ff = fl[j + i].split() data['coords'][j, 0] = float(ff[3]) data['coords'][j, 1] = float(ff[4]) data['coords'][j, 2] = float(ff[5]) else: i += 1 i = 0 while i < len(fl): if " Potential X Y Z" in fl[ i]: i = i + 2 + self._natoms data['gridesp'] = [] while not ("----" in fl[i]): ff = fl[i].split() data['gridesp'].append(float(ff[1])) i += 1 data['gridesp'] = np.asarray(data['gridesp'], dtype=np.float) else: i += 1 except: data = None if data is None: result.errored = True elif not ('energy' in data) or data['energy'] == 0.: result.errored = True else: result.energy = data['energy'] result.energy *= const.physical_constants['Hartree energy'][0] / ( const.kilo * const.calorie / const.Avogadro ) # Hartree to kcal/mol result.coords = np.atleast_3d(data['coords']) if 'gridesp' in data: result.esp_points = np.squeeze(np.asarray(self.esp_points)) result.esp_values = data['gridesp'] result.esp_values *= const.angstrom / const.physical_constants[ 'Bohr radius'][0] # 1/Bohr to 1/Angstrom if 'dipole' in data: result.dipole = data['dipole'] if 'quadrupole' in data: result.quadrupole = data['quadrupole'] if 'mulliken' in data: result.mulliken = data['mulliken'] return result
def _readOutput(self, directory): result = QMResult() with open(os.path.join(directory, 'g09.out')) as f: fl = f.readlines() try: data = {} for i in range(len(fl)): if "Dipole moment (field-independent basis, Debye):" in fl[i]: s = fl[i + 1].split() data['dipole'] = [float(s[1]), float(s[3]), float(s[5]), float(s[7])] if "Traceless Quadrupole moment (field-independent basis, Debye-Ang):" in fl[i]: s1 = fl[i + 1].split() s2 = fl[i + 2].split() data['quadrupole'] = [float(s1[1]), float(s1[3]), float(s1[5]), float(s2[1]), float(s2[3]), float(s2[5])] if "Mulliken atomic charges:" in fl[i] or "Mulliken charges:" in fl[i]: data['mulliken'] = [] for j in range(self._natoms): data['mulliken'].append(float(fl[i + 2 + j].split()[2])) for l in fl: if "SCF Done: E(RHF) = " in l: ff = l.split() data['energy'] = float(ff[4]) if "SCF Done: E(RB3LYP) = " in l: ff = l.split() data['energy'] = float(ff[4]) i = 0 while i < len(fl): if "Number Number Type X Y Z" in fl[i]: i += 2 data['coords'] = np.zeros((self._natoms, 3)) for j in range(self._natoms): ff = fl[j + i].split() data['coords'][j, 0] = float(ff[3]) data['coords'][j, 1] = float(ff[4]) data['coords'][j, 2] = float(ff[5]) else: i += 1 i = 0 while i < len(fl): if " Potential X Y Z" in fl[i]: i = i + 2 + self._natoms data['gridesp'] = [] while not ("----" in fl[i]): ff = fl[i].split() data['gridesp'].append(float(ff[1])) i += 1 data['gridesp'] = np.asarray(data['gridesp'], dtype=np.float) else: i += 1 except: data = None if data is None: result.errored = True elif not ('energy' in data) or data['energy'] == 0.: result.errored = True else: result.energy = data['energy'] result.energy *= const.physical_constants['Hartree energy'][0]/(const.kilo*const.calorie/const.Avogadro) # Hartree to kcal/mol result.coords = np.atleast_3d(data['coords']) if 'gridesp' in data: result.esp_points = np.squeeze(np.asarray(self.esp_points)) result.esp_values = data['gridesp'] result.esp_values *= const.angstrom/const.physical_constants['Bohr radius'][0] # 1/Bohr to 1/Angstrom if 'dipole' in data: result.dipole = data['dipole'] if 'quadrupole' in data: result.quadrupole = data['quadrupole'] if 'mulliken' in data: result.mulliken = data['mulliken'] return result