def assign_elf10_am1_bond_orders( molecule: Molecule, max_confs: int = 800, rms_threshold: float = 1.0 ) -> Molecule: """Generate ELF10 AM1 WBOs for a molecule. Parameters ---------- molecule The molecule to compute WBOs for. max_confs : int, optional, default=800 Max number of conformers to generate rms_threshold The minimum RMS value [Angstrom] at which two conformers are considered redundant and one is deleted. Returns ------- A new molecule which contains ELF10 AM1 Wiberg Bond orders. """ molecule = copy.deepcopy(molecule) # Store the atom map separately in case it gets removed by a TK. atom_map = molecule.properties.pop("atom_map", None) # Generate a set of ELF10 conformers. molecule = _generate_conformers(molecule, max_confs, rms_threshold) molecule.apply_elf_conformer_selection() per_conformer_bond_orders = [] for conformer in molecule.conformers: molecule.assign_fractional_bond_orders("am1-wiberg", use_conformers=[conformer]) per_conformer_bond_orders.append( [bond.fractional_bond_order for bond in molecule.bonds] ) bond_orders = [*numpy.mean(per_conformer_bond_orders, axis=0)] for bond, bond_order in zip(molecule.bonds, bond_orders): bond.fractional_bond_order = bond_order # Restore the atom map. if atom_map is not None: molecule.properties["atom_map"] = atom_map return molecule
def label_function(molecule: Molecule) -> Dict[str, torch.Tensor]: """Generates a set of train / val / test labels for a given molecule.""" from simtk import unit # Generate a set of ELF10 conformers. molecule.generate_conformers(n_conformers=800, rms_cutoff=0.05 * unit.angstrom) molecule.apply_elf_conformer_selection() partial_charges = [] for conformer in molecule.conformers: molecule.assign_partial_charges("am1-mulliken", use_conformers=[conformer]) partial_charges.append( molecule.partial_charges.value_in_unit(unit.elementary_charge)) return { "am1-charges": torch.from_numpy(numpy.mean(partial_charges, axis=0)).float() }