def predict_charges(name, predictor, device, output): """ returns a mol2 file containing charges obtained by inference Example: predict-charges --device=cpu --output=benzene.npa.mp2 benzene.mol2 """ start = time.time() dev = torch.device(device=device) mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() pars = dm.get_parametrization() model = torch.load(predictor, map_location=dev).to(dev, ) param = Parametrizer(model, device=dev) pars = param.parametrize(name, pars) dm.read(pars) charges = dm.get_a2md_charges() if output is None: for i, (sym, coords, q) in enumerate( zip(dm.get_symbols(), dm.get_coordinates(), charges)): print("{:8d} {:8s} {:8.4e} {:8.4e} {:8.4e} {:8.4e}".format( i, sym, coords[0], coords[1], coords[2], q)) else: mm = Mol2(file=name) mm.charges = charges mm.write(file=output) print("TE : {:12.4f}".format(time.time() - start))
def rename_atoms(mol: Mol2, new_names: Dict): n = mol.get_number_atoms() if len(new_names['_ATOMS']) != n: raise RuntimeError("number of atoms does not match") new_anames = [i[0] for i in new_names['_ATOMS']] new_segmentsidx = [i[1] for i in new_names['_ATOMS']] new_segments = [new_names['_SEGMENTS'][i[1]] for i in new_names['_ATOMS']] mol.atom_names = new_anames mol.segments = new_segments mol.segment_idx = new_segmentsidx return mol
def split_space(mm: Mol2, fun: Callable): """ split space --- divides fun in n functions centered around atoms :param mm: :param fun: :return: """ r = mm.get_coordinates(units='au') n = mm.get_number_atoms() for i in range(n): r0 = r[i, :] yield lambda x: fun(x + r0) * (voronoi(x + r0, r) == i)
def integrate_density_functional_gradient(functional: Callable, mol: Mol2, nfuns: int, grid='coarse', res=100): r = mol.get_coordinates(units='au') n = mol.get_number_atoms() functional_value = np.zeros(nfuns, dtype='float64') for i in range(n): r0 = r[i, :] fx = lambda x: functional(x + r0) * (voronoi(x + r0, r) == i).reshape( -1, 1) functional_value += pi_lebedev_m(fx, nfuns, radial_res=res, grid=grid) return functional_value
def convert(mol : Mol2): G = nx.Graph() for i in range(mol.get_number_atoms()): G.add_node(i, **mol.get_atom(i)) bonds = mol.get_bonds() bonds = bonds - 1 for i in range(mol.get_number_bonds()): G.add_edge(bonds[i, 0], bonds[i, 1]) bonds, angles, dihedrals = decompose_molecule_graph(G) dbonds = np.zeros(len(bonds), dtype='float64') dangles = np.zeros(len(angles), dtype='float64') ddihedrals = np.zeros(len(dihedrals), dtype='float64') for i in range(len(bonds)): atom1, atom2 = bonds[i].split("|") atom1 = int(atom1) atom2 = int(atom2) x1 = G.nodes[atom1]['coordinates'] x2 = G.nodes[atom2]['coordinates'] dbonds[i] = distance(x1, x2) for i in range(len(angles)): ends, center = angles[i].split(",") atom1, atom3 = ends.split("|") atom1 = int(atom1) atom3 = int(atom3) atom2 = int(center) x1 = G.nodes[atom1]['coordinates'] x2 = G.nodes[atom2]['coordinates'] x3 = G.nodes[atom3]['coordinates'] dangles[i] = angle(x1, x2, x3) for i in range(len(dihedrals)): ends, center = dihedrals[i].split(",") atom1, atom4 = ends.split("|") atom2, atom3 = center.split("|") atom1 = int(atom1) atom3 = int(atom3) atom2 = int(atom2) atom4 = int(atom4) x1 = G.nodes[atom1]['coordinates'] x2 = G.nodes[atom2]['coordinates'] x3 = G.nodes[atom3]['coordinates'] x4 = G.nodes[atom4]['coordinates'] ddihedrals[i] = dihedral(x1, x2, x3, x4) return dbonds, dangles, ddihedrals
def __generate_ppp(name, output, parametrization='default'): start = time.time() if output is None: output = name.replace('.mol2', '.ppp') mm = Mol2(name) dm = a2md_from_mol(mm) if parametrization == 'default': params = dm.parametrization_default elif parametrization == 'extended': params = dm.parametrization_extended elif parametrization == 'spherical': params = dm.parametrization_spherical elif parametrization == 'harmonic': params = dm.parametrization_harmonic else: print( "unknown parametrization. please, use either default, extended, spherical or harmonic" ) sys.exit() dm.parametrize(params) with open(output, "w") as f: json.dump(dm.get_parametrization(), f, indent=4, sort_keys=True) print("TE : {:12.4f}".format(time.time() - start))
def __update_many_mol2(inp, suffix, wfn_suffix, g09_suffix, input_type, charges): """ updates many mol2 files at the same time """ from a2mdio.qm import WaveFunction, GaussianLog from a2mdio.molecules import UNITS_TABLE if input_type == 'json': with open(inp) as f: input_contents = json.load(f) elif input_type == 'csv': with open(inp) as f: input_contents = [i.strip() for i in f.readlines()] else: print("unknown format. use either csv or json") sys.exit() for name in input_contents: mm = Mol2(name + '.mol2') wfn = name + wfn_suffix gaussian_log = name + g09_suffix wfn_instance = WaveFunction(file=wfn, prefetch_dm=False, verbose=False) glog = GaussianLog(file=gaussian_log, method='', charges=charges, verbose=False) gdict = glog.read() mm.coordinates = wfn_instance.get_coordinates() * UNITS_TABLE['au']['angstrom'] mm.charges = np.array(gdict['charges'], dtype='float64') mm.write(name + suffix)
def optimize(molecule, model, device, output, tolerance, steps): start = time.time() mm = Mol2(molecule) pos = mm.get_coordinates() labels = ''.join(mm.get_symbols()) device=torch.device(device) if model.lower() == 'ani1x': model = torchani.models.ANI1x() elif model.lower() == 'ani1ccx': model = torchani.models.ANI1ccx() else: print("unknwon model {:s}".format(model)) sys.exit(1) assert isinstance(model, torchani.models.ANI1x) or isinstance(model, torchani.models.ANI1ccx) atom_group = Atoms(symbols=labels, positions=pos, calculator=model.ase()) print("\tenergy {:12.4f}".format(atom_group.get_total_energy())) opt = BFGS(atom_group, logfile=None) res = opt.run(fmax=tolerance, steps=steps) if res: print("optimization completed, time {:12.4f}".format(time.time() - start)) print("initial energy {:12.4f}".format(atom_group.get_total_energy())) opt_pos = atom_group.get_positions() mm.coordinates = opt_pos if output is not None: mm.write(output) sys.exit(0) else: print("maximum number of steps reached, time {:12.4f}") print("final energy {:12.4f}".format(atom_group.get_total_energy())) sys.exit(1)
def md(molecule, model, device, output, nsteps, temperature, step, friction): start = time.time() mm = Mol2(molecule) pos = mm.get_coordinates() labels = ''.join(mm.get_symbols()) device = torch.device(device) if model.lower() == 'ani1x': model = torchani.models.ANI1x() elif model.lower() == 'ani1ccx': model = torchani.models.ANI1ccx() else: print("unknwon model {:s}".format(model)) sys.exit(1) assert isinstance(model, torchani.models.ANI1x) or isinstance(model, torchani.models.ANI1ccx) atom_group = Atoms(symbols=labels, positions=pos, calculator=model.ase()) print("step {:12d}\tenergy {:12.4f}".format(0, atom_group.get_total_energy())) dyn = Langevin(atom_group, 1*units.fs, temperature*units.kB, friction) for i in range(nsteps): dyn.run(step) print("step {:12d}\tenergy {:12.4f}".format((i + 1)*step, atom_group.get_total_energy())) mm.coordinates = atom_group.get_positions() if output is not None: mm.write(output + '_{:06d}.mol2'.format(i)) print("time {:12.4f}".format(time.time() - start)) sys.exit(0)
def write_dx(name, param_file, output, expand, res, kind): """ writes a dx volumetric file. This type of file can be used to 3d-visualize electron density using software as chimera, PyMol or VMD Example: write-dx --output=benzene.a2md.dx --expand=3.0 --res=0.25 --kind=density benzene.mol2 benzene.ppp Note: resolution and expand units are Bohr """ start = time.time() mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() with open(param_file) as f: dm.read(json.load(f)) dx = dm.eval_volume(spacing=expand, resolution=res, kind=kind) if output is None: dx.write(name.replace('.mol2', '') + '.dx') else: dx.write(output) print("writting to : {:s}".format(output)) print("TE : {:12.4f}".format(time.time() - start))
def compare_sample(name, reference, candidate, coordinates, metric, reference_type, candidate_type): start = time.time() mm = Mol2(name) if metric in ['mse', 'mlse', 'rmse']: if metric == 'mse': metric_function = lambda x, y: np.power( (x - y), 2.0).sum() / x.shape[0] elif metric == 'rmse': metric_function = lambda x, y: np.sqrt( np.power((x - y), 2.0).sum() / x.shape[0]) elif metric == 'mlse': metric_function = lambda x, y: np.log(np.power( (x - y), 2.0)).sum() / x.shape[0] else: print("unkown metric. please, use either mse, rmse or mlse") sys.exit() coordinates = np.loadtxt(coordinates) reference_d = admin_sources(mm, reference, reference_type) candidate_d = admin_sources(mm, candidate, candidate_type) reference_p = reference_d.eval(coordinates) candidate_p = candidate_d.eval(coordinates) value = metric_function(reference_p, candidate_p) print("{:24s} {:24s} SAMPLE-{:s} {:18.8e} {:8.4f}".format( reference, candidate, metric, value, time.time() - start))
def evaluate(name, param_file, coordinates, output): """ reads a model and runs an evaluation upon the specified coordinates """ start = time.time() mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() with open(param_file) as f: dm.read(json.load(f)) try: coordinates = np.loadtxt(coordinates, dtype='float64') except ValueError: print("could not read file. please, use space separated values") print("sed -i \"s/,/ /g\" COORDINATES") sys.exit() except FileNotFoundError: print("file not found") sys.exit() assert (type(coordinates) is np.ndarray) prediction = dm.eval(coordinates) assert (type(prediction) is np.ndarray) if output is None: for i in range(prediction.size): print("{:12.4e} {:12.4e} {:12.4e} {:12.4e}".format( coordinates[i, 0], coordinates[i, 1], coordinates[i, 2], prediction[i])) else: # noinspection PyTypeChecker np.savetxt(output, np.stack([coordinates, prediction], axis=1)) print("TE : {:12.4f}".format(time.time() - start))
def __random_rotation(name, out, n=100): mm = Mol2(name) x = mm.get_coordinates() x = x - x.mean(axis=0) for i in range(n): u = (2.0 * np.random.rand(1)) - 1.0 u = np.clip(u, -0.999999, 0.999999) theta = np.arccos(u) # * np.sign(u) phi = np.random.rand(1) * 2.0 * np.pi rotx = np.array([ [1.0, 0.0, 0.0], [0.0, np.cos(theta), -np.sin(theta)], [0.0, np.sin(theta), np.cos(theta)] ], dtype='float64') rotz = np.array([ [np.cos(phi), -np.sin(phi), 0.0], [np.sin(phi), np.cos(phi), 0.0], [0.0, 0.0, 1.0] ], dtype='float64') y = np.dot(rotz, x.T) y = np.dot(rotx, y) mm.coordinates = y.T mm.write(out + '_%03d.mol2' % i)
def predict_model(name, predictor, device, output): """ returns a ppp containing an am2d density model obtained by neural network inference Example: predict-model --device=cpu --output=benzene.ml.ppp benzene.mol2 """ start = time.time() dev = torch.device(device=device) mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() pars = dm.get_parametrization() model = torch.load(MODELS[predictor], map_location=dev).to(dev, ) param = Parametrizer(model, device=dev) pars = param.parametrize(name, pars) if output is None: print(json.dumps(pars, indent=4)) else: with open(output, 'w') as f: json.dump(pars, f, indent=4, sort_keys=True) print("TE : {:12.4f}".format(time.time() - start))
def __prepare_qm(name, charge, multiplicity, wfn, population, basis, method, nprocs, program): start = time.time() mm = Mol2(name) adcs = [] if population != "none": adcs.append('pop={:s}'.format(population)) if wfn: adcs.append('output=wfn') if method == 'MP2': adcs.append('density=current') mm.charges = (charge / mm.get_number_atoms()) * np.ones( mm.get_number_atoms(), dtype='float64') mm.multiplicity = multiplicity qmstp = QmSetUp(basis=basis, method=method, calculation_type='single', nprocs=nprocs, additional_commands=adcs, verbose=False) if program == 'g09': qmstp.write_g09(name.replace('.mol2', '.g09.input'), mm, wfn) elif program == 'orca': qmstp.write_orca(name.replace('.mol2', '.orca'), mm) else: print("unknown program. Use either ORCA or G09") sys.exit() print("TE : {:12.4f}".format(time.time() - start))
def __read_mol2(file, xyz_array, elem_array, topo_array, charge_array): from a2mdio.molecules import Mol2 mol2_instance = Mol2(file, verbose=False) labels = mol2_instance.get_labels() charges = mol2_instance.get_charge(kind='total') coords = mol2_instance.get_coordinates() * ANG2AU topology_matrix = mol2_instance.get_bonds() for i in range(mol2_instance.get_number_atoms()): charge_array.append(float(charges[i])) elem_array.append(labels[i]) xyz_array.append([ float(coords[i, 0]), float(coords[i, 1]), float(coords[i, 2]) ]) for i in range(mol2_instance.get_number_atoms()): topo_array.append([]) for i in range(mol2_instance.get_number_bonds()): begin = int(topology_matrix[i, 0]) end = int(topology_matrix[i, 1]) topo_array[begin - 1].append(end - 1) topo_array[end - 1].append(begin - 1)
def parametrize(self, mol, params): """ :param mol: :param params :return: """ if not isinstance(mol, Mol2): try: mol = Mol2(file=mol) except ValueError: raise IOError("unknown format for mol. Please, use Mol2 or str") coords = torch.tensor(mol.get_coordinates(), device=self.device, dtype=torch.float).unsqueeze(0) labels = convert_label2tensor(mol.get_atomic_numbers(), device=self.device).unsqueeze(0) connectivity = torch.tensor(mol.get_bonds(), dtype=torch.long, device=self.device).unsqueeze(0) charge = torch.tensor(mol.charges + mol.atomic_numbers, dtype=torch.float, device=self.device).unsqueeze(0) natoms = mol.get_number_atoms() nbonds = mol.get_number_bonds() connectivity -= 1 int_iso = torch.zeros(1, natoms, 2) int_aniso = torch.zeros(1, nbonds, 4) for fun in params: center = fun['center'] funtype, pos = match_fun_names(fun) if funtype == 'core': charge[0, center] -= integrate_from_dict(fun) elif funtype in 'iso': int_iso[0, center, pos] = integrate_from_dict(fun) elif funtype in 'aniso': idx, col = self.match_bond(connectivity, fun) int_aniso[0, idx, col + pos] = integrate_from_dict(fun) int_iso = int_iso.to(self.device) int_aniso = int_aniso.to(self.device) _, _, iso_out, aniso_out = self.model.forward_coefficients(labels, connectivity, coords, charge, int_iso, int_aniso) if iso_out.is_cuda: iso_out = iso_out.squeeze(0).cpu().data.numpy() aniso_out = aniso_out.squeeze(0).cpu().data.numpy() else: iso_out = iso_out.squeeze(0).data.numpy() aniso_out = aniso_out.squeeze(0).data.numpy() for fun in params: center = fun['center'] funtype, pos = match_fun_names(fun) if funtype == 'core': continue if funtype == 'iso': fun['coefficient'] = iso_out[center, pos].item() elif funtype == 'aniso': idx, col = self.match_bond(connectivity, fun) fun['coefficient'] = aniso_out[idx, col + pos].item() return params
def genamd_from_mol2(mol: Mol2, device: torch.device, nfuns: int): labels = mol.get_symbols() centers = torch.tensor(mol.get_coordinates(units='au'), dtype=torch.float, device=device) labels = torch.tensor([SYMBOL2NN[i] for i in labels], dtype=torch.long, device=device) centers.unsqueeze_(0) labels.unsqueeze_(0) natoms = mol.get_number_atoms() coefficients = torch.ones(1, natoms, nfuns, dtype=torch.float, device=device) return labels, centers, coefficients
def volume(name, reference, reference_type, epsilon, grid, resolution): start = time.time() mm = Mol2(name) reference_d = admin_sources(mm, reference, reference_type) volf = vdwvolume_functional(reference_d.eval, eps=epsilon) vol = integrate_density_functional(volf, mm, res=resolution, grid=grid) print("{:24s} VOL(au) {:18.8e} {:8.4f}".format(reference, vol, time.time() - start))
def __generate_ppp(name, output): start = time.time() if output is None: output = name.replace('.mol2', '.ppp') mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() with open(output, "w") as f: json.dump(dm.get_parametrization(), f, indent=4, sort_keys=True) print("TE : {:12.4f}".format(time.time() - start))
def dkl(name, reference, candidate, reference_type, candidate_type, grid, resolution): start = time.time() mm = Mol2(name) reference_d = admin_sources(mm, reference, reference_type) candidate_d = admin_sources(mm, candidate, candidate_type) dklf = dkl_functional(ref=reference_d.eval, fun=candidate_d.eval) dklv = integrate_density_functional(dklf, mm, res=resolution, grid=grid) print("{:24s} {:24s} DKL {:18.8e} {:8.4f}".format(reference, candidate, dklv, time.time() - start))
def mse(name, reference, candidate, reference_type, candidate_type, grid, resolution): start = time.time() mm = Mol2(name) reference_d = admin_sources(mm, reference, reference_type) candidate_d = admin_sources(mm, candidate, candidate_type) msef = mse_functional(ref=reference_d.eval, fun=candidate_d.eval) msev = integrate_density_functional(msef, mm, res=resolution, grid=grid) print("{:24s} {:24s} MSE {:18.8e} {:8.4f}".format(reference, candidate, msev, time.time() - start))
def a2md_from_mol(mol: Mol2): """ returns the density model associated to a Mol2 :param mol: :type mol: Mol2 :return: :rtype: Molecule """ an = mol.get_atomic_numbers() coords = mol.get_coordinates(units="au") charge = mol.get_absolute_charges() topology = mol.get_bonds() segments = mol.segment_idx topo_array = [] for i in range(mol.get_number_atoms()): topo_array.append([]) for i in range(mol.get_number_bonds()): begin = int(topology[i, 0]) end = int(topology[i, 1]) topo_array[begin - 1].append(end - 1) topo_array[end - 1].append(begin - 1) return Molecule(coordinates=coords, atomic_numbers=an, charge=charge, topology=topo_array, segments=segments)
def fetch(self, item): identifier = self.ids[item] mm = Mol2(self.mol_path / '{:s}.mol2'.format(identifier)) na = mm.get_number_atoms() nb = mm.get_number_bonds() coords_tensor = torch.zeros(self.max_atoms, 3, dtype=self.dtype, device=torch.device('cpu')) labels_tensor = torch.ones( self.max_atoms, dtype=torch.long, device=torch.device('cpu')) * -1 connectivity_tensor = torch.ones( self.max_bonds, 2, device=torch.device('cpu'), dtype=torch.long) * -1 charges_tensor = torch.zeros(self.max_atoms, dtype=self.dtype, device=torch.device('cpu')) segment_tensor = torch.zeros(self.max_atoms, dtype=torch.long, device=torch.device('cpu')) coords_tensor[:na, :] = torch.tensor(mm.get_coordinates(), device=torch.device('cpu'), dtype=self.dtype) labels_tensor[:na] = convert_label2tensor(mm.get_atomic_numbers(), device=self.device) connectivity_tensor[:nb, :] = torch.tensor(mm.get_bonds() - 1, device=torch.device('cpu'), dtype=torch.uint8) charges_tensor[:na] = torch.tensor(mm.get_absolute_charges(), device=self.device, dtype=self.dtype) segment_tensor[:na] = torch.tensor(mm.segment_idx, device=self.device, dtype=self.dtype) segments = [i for i in mm.get_all_segs()] segments = [i[:-1] for i in segments] segcharges = torch.tensor( [self.dcharges[i]['population'] for i in segments], device=self.device, dtype=self.dtype) return [ i.to(self.device) for i in [ labels_tensor, connectivity_tensor, coords_tensor, charges_tensor, segment_tensor, segcharges ] ]
def __update_mol2(name, wfn, gaussian_log, output, charges): """ updates a mol2 file using npa charges from gaussian output and coordinates of a wfn """ from a2mdio.qm import WaveFunction, GaussianLog from a2mdio.molecules import UNITS_TABLE mm = Mol2(name) wfn_instance = WaveFunction(file=wfn, prefetch_dm=False, verbose=False) glog = GaussianLog(file=gaussian_log, method='', charges=charges, verbose=False) gdict = glog.read() mm.coordinates = wfn_instance.get_coordinates() * UNITS_TABLE['au']['angstrom'] mm.charges = np.array(gdict['charges'], dtype='float64') mm.write(output)
def fetch(self, item): """ :param item: :return: """ import math identifier = self.ids[item] mm = Mol2(self.mol_path / '{:s}.mol2'.format(identifier)) with open(self.params_path / '{:s}.ppp'.format(identifier)) as f: params = json.load(f) na = mm.get_number_atoms() nb = mm.get_number_bonds() coords_tensor = torch.zeros(self.max_atoms, 3, dtype=self.dtype, device=torch.device('cpu')) labels_tensor = torch.ones(self.max_atoms, dtype=torch.long, device=torch.device('cpu')) * -1 connectivity_tensor = torch.ones(self.max_bonds, 2, device=torch.device('cpu'), dtype=torch.long) * -1 charges_tensor = torch.zeros(self.max_atoms, dtype=self.dtype, device=torch.device('cpu')) isotropic_params = torch.zeros(self.max_atoms, 2, dtype=self.dtype, device=torch.device('cpu')) anisotropic_params= torch.zeros(self.max_bonds, 4, dtype=self.dtype, device=torch.device('cpu')) isotropic_integrals= torch.zeros(self.max_atoms, 2, dtype=self.dtype, device=torch.device('cpu')) anisotropic_integrals = torch.zeros(self.max_bonds, 4, dtype=self.dtype, device=torch.device('cpu')) coords_tensor[:na, :] = torch.tensor(mm.get_coordinates(), device=torch.device('cpu'), dtype=self.dtype) labels_tensor[:na] = convert_label2tensor(mm.get_atomic_numbers(), device=self.device) connectivity_tensor[:nb, :] = torch.tensor(mm.get_bonds() - 1, device=torch.device('cpu'), dtype=torch.uint8) charges_tensor[:na] = torch.tensor(mm.get_absolute_charges(), device=self.device, dtype=self.dtype) for fun in params: if math.isnan(fun['coefficient']): raise IOError("issue with instance {:s}".format(identifier)) funtype, pos = self.match_method(fun) if funtype == 'core': charges_tensor[fun['center']] -= self.calculate_integral(fun) elif funtype == 'iso': isotropic_params[fun['center'], pos] = fun['coefficient'] isotropic_integrals[fun['center'], pos] = self.calculate_integral(fun) elif funtype == 'aniso': bond_idx, col = self.match_bond(connectivity_tensor, fun, nb) anisotropic_params[bond_idx, col + pos] = fun['coefficient'] anisotropic_integrals[bond_idx, col + pos] = self.calculate_integral(fun) return [ i.to(self.device) for i in [labels_tensor, connectivity_tensor, coords_tensor, charges_tensor, isotropic_integrals, anisotropic_integrals, isotropic_params, anisotropic_params] ]
def __init__(self, file=None): """ :param file: """ from a2mdio.molecules import Mol2 A2MDBaseClass.__init__(self, name='symfeats', verbose=False) if file is not None: self.__mol = Mol2(file=file, verbose=False) self.__mol.change_units('au') else: self.__mol = None self.__x = None self.__l = None
def predict_charges(name, predictor, device, output): start = time.time() dev = torch.device(device=device) mm = Mol2(name) dm = a2md_from_mol(mm) dm.parametrize() pars = dm.get_parametrization() model = torch.load(predictor, map_location=dev).to(dev) param = Parametrizer(model, device=dev) pars = param.parametrize(name, pars) dm.read(pars) charges = dm.get_a2md_charges() if output is None: for i, (sym, coords, q) in enumerate( zip(dm.get_symbols(), dm.get_coordinates(), charges)): print("{:8d} {:8s} {:8.4e} {:8.4e} {:8.4e} {:8.4e}".format( i, sym, coords[0], coords[1], coords[2], q)) else: mm = Mol2(file=name) mm.charges = charges mm.write(file=output) print("TE : {:12.4f}".format(time.time() - start))
def __extract_forces(name, g09log, output, output_format): """ extracts forces in Ha/Angstrom from g09 output """ with open(g09log) as f: n, fx = forces([i.strip() for i in f.readlines()]) if output_format == 'mol2': mm = Mol2(name) mm.coordinates = np.array(fx) mm.write(output) elif output_format == 'csv': np.savetxt(output, np.array(fx), delimiter=' ', fmt='%12.6e') else: for fx_ in fx: print("{:18.6e} {:18.6e} {:18.6e}".format(fx_[0], fx_[1], fx_[2]))
def energy(molecule, model, device): mm = Mol2(molecule) pos = mm.get_coordinates() labels = ''.join(mm.get_labels()) device = torch.device(device) if model.lower() == 'ani1x': model = torchani.models.ANI1x() elif model.lower() == 'ani1ccx': model = torchani.models.ANI1ccx() else: print("unknwon model {:s}".format(model)) sys.exit(1) assert isinstance(model, torchani.models.ANI1x) or isinstance(model, torchani.models.ANI1ccx) atom_group = Atoms(symbols=labels, positions=pos, calculator=model.ase()) print("{:26s} {:18.6e}".format(molecule, atom_group.get_potential_energy() / units.Hartree)) sys.exit(0)