def tet_fix_stereo(smiles, frag): mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f._find_stereo() frag = chemi.smiles_to_oemol(frag, add_atom_map=True) fixed = f._fix_stereo(frag) assert f._check_stereo(fixed) == True
def test_stereo_parent(self): """Test non isomeric and isomeric parent molecule SMILES""" smiles = 'NC(C)(F)C(=O)O' isomeric_smiles_r = 'N[C@](C)(F)C(=O)O' isomeric_smiles_s = 'N[C@@](C)(F)C(=O)O' mol_1 = chemi.smiles_to_oemol(smiles) mol_2 = chemi.smiles_to_oemol(isomeric_smiles_r) mol_3 = chemi.smiles_to_oemol(isomeric_smiles_s) self.assertFalse(fragmenter.fragment._generate_fragments(mol_1)) fragmenter.fragment._generate_fragments(mol_1, strict_stereo=False) fragmenter.fragment._generate_fragments(mol_2) fragmenter.fragment._generate_fragments(mol_3)
def test_smiles_to_oemol(): from openeye import oechem mol = chemi.smiles_to_oemol('CCCC') assert isinstance(mol, oechem.OEMol) assert oechem.OEMolToSmiles(mol) == 'CCCC' assert mol.GetTitle() == 'butane' mol = chemi.smiles_to_oemol('CCCC', normalize=False) assert mol.GetTitle() == '' mol = chemi.smiles_to_oemol('CCCC', add_atom_map=True) assert oechem.OEMolToSmiles( mol ) == '[H:5][C:1]([H:6])([H:7])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C:2]([H:8])([H:9])[H:10]'
def test_formal_charge(self): """Test formal charge""" mol_1 = chemi.smiles_to_oemol('c1cc(c[nH+]c1)c2ccncn2') charge = chemi.get_charge(mol_1) self.assertEqual(charge, 1) mol_2 = chemi.smiles_to_oemol('C[NH+]1CC[NH+](CC1)Cc2ccccc2') charge = chemi.get_charge(mol_2) self.assertEqual(charge, 2) mol_3 = chemi.smiles_to_oemol('CCC(C)(C)C(=O)[O-]') charge = chemi.get_charge(mol_3) self.assertEqual(charge, -1)
def test_expand_protonation_states(self): """Test expand protonation states""" smiles = 'C5=C(C1=CN=CC=C1)N=C(NC2=C(C=CC(=C2)NC(C3=CC=C(C=C3)CN4CCN(CC4)C)=O)C)N=C5' molecule = chemi.smiles_to_oemol(smiles) protonation = fragmenter.fragment._expand_states(molecule) protonation_1 = { 'Cc1ccc(cc1Nc2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)CN5CCN(CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)CN5CC[NH+](CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)C[NH+]5CCN(CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)C[NH+]5CC[NH+](CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)CN5CCN(CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)CN5CC[NH+](CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)C[NH+]5CCN(CC5)C', 'Cc1ccc(cc1Nc2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)C[NH+]5CC[NH+](CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)CN5CCN(CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)CN5CC[NH+](CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)C[NH+]5CCN(CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3ccc[nH+]c3)NC(=O)c4ccc(cc4)C[NH+]5CC[NH+](CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)CN5CCN(CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)CN5CC[NH+](CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)C[NH+]5CCN(CC5)C', 'Cc1ccc(cc1[N-]c2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)C[NH+]5CC[NH+](CC5)C' } protonation_2 = set() for mol in protonation: protonation_2.add( mol_to_smiles(mol, mapped=False, explicit_hydrogen=False, isomeric=True)) intersection = protonation_1.intersection(protonation_2) self.assertEqual(len(intersection), len(protonation_1)) self.assertEqual(len(intersection), len(protonation_2))
def test_expand_tautomers(self): """Test expand tautomer""" smiles_1 = 'c1ccc2c(c1)C=CCC2=O' smiles_2 = 'c1ccc2c(c1)cccc2O' molecule_1 = chemi.smiles_to_oemol(smiles_1) molecule_2 = chemi.smiles_to_oemol(smiles_2) tautomers_1 = fragmenter.fragment.expand_states(molecule_1, protonation=False, tautomers=True, stereoisomers=False) tautomers_2 = fragmenter.fragment.expand_states(molecule_2, protonation=False, tautomers=True, stereoisomers=False) self.assertEqual(tautomers_1, tautomers_2)
def test_generate_conformers(): mol = chemi.smiles_to_oemol('CCCCCCC') confs = chemi.generate_conformers(mol, max_confs=1) assert confs.GetMaxConfIdx() == 1 confs = chemi.generate_conformers(mol) assert confs.GetMaxConfIdx() == 3
def test_add_substituent(): smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() assert mol_to_smiles(f.fragments[(3, 5)], mapped=False, explicit_hydrogen=False) == 'CCCCC' mol = f.fragments[(3, 5)] atoms = set() bonds = set() for a in mol.GetAtoms(): if a.IsHydrogen(): continue atoms.add(a.GetMapIdx()) for b in mol.GetBonds(): a1 = b.GetBgn() a2 = b.GetEnd() if a1.IsHydrogen() or a2.IsHydrogen(): continue bonds.add((a1.GetMapIdx(), a2.GetMapIdx())) mol = f._add_next_substituent(atoms, bonds, target_bond=(3, 5)) assert mol_to_smiles(mol, mapped=False, explicit_hydrogen=False) == 'CCCCCC'
def test_to_qcschema_mols(): smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() qcschema_mol = f.to_qcschema_mols() assert len(qcschema_mol) == 2
def test_depict_fragments(engine): mol = chemi.smiles_to_oemol('CCCCC') if engine == 'WBO': f = fragmenter.fragment.WBOFragmenter(mol) if engine =='combinatorial': f = fragmenter.fragment.CombinatorialFragmenter(mol) f.fragment() assert f.depict_fragments('test.pdf') == True
def test_td_inputs(): smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() td_inputs = f.to_torsiondrive_json() assert len(td_inputs) == 2
def test_get_ring_and_fgroup(input, bond, output): mol = chemi.smiles_to_oemol(input) f = fragmenter.fragment.PfizerFragmenter(mol) atoms, bonds = f._get_torsion_quartet(bond) l_atoms = len(atoms) l_bonds = len(bonds) atoms_2, bonds_2 = f._get_ring_and_fgroups(atoms, bonds) assert (l_atoms == len(atoms_2)) == output assert (l_bonds == len(bonds_2)) == output
def generate_grid_conformers(): mol = chemi.smiles_to_oemol('CCCC') dihedrals = [(0, 2, 3, 1), (3, 2, 0, 4)] intervals = [30, 90] grid = chemi.generate_grid_conformers(mol, dihedrals=dihedrals, intervals=intervals) assert grid.GetMaxConfIdx() == 48
def test_cap_open_valance(input, bond, output): from openeye import oechem mol = chemi.smiles_to_oemol(input) f = fragmenter.fragment.PfizerFragmenter(mol) atoms, bonds = f._get_torsion_quartet(bond) atoms, bonds = f._get_ring_and_fgroups(atoms, bonds) f._cap_open_valence(atoms, bonds, bond) # Check that carbon bonded to N was added assert f.molecule.GetAtom(oechem.OEHasMapIdx(output))
def test_to_json(): smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() json_dict = f.to_json() assert len(json_dict) == 2 assert list(json_dict.keys())[0] == 'CCCCC' assert 'provenance' in json_dict['CCCCC'] assert 'cmiles_identifiers' in json_dict['CCCCC']
def test_get_charges(keep_confs, output): mol = chemi.smiles_to_oemol('CCCCCCC') if output == 'error': with pytest.raises(ValueError): chemi.get_charges(mol, keep_confs=keep_confs) else: charged = chemi.get_charges(mol, keep_confs=keep_confs) for i, c in enumerate(charged.GetConfs()): i += 1 assert i == output
def test_build_WBOfragment(): """ Test build fragment""" from openeye import oechem smiles = 'CCCCC' mol = chemi.smiles_to_oemol(smiles) oechem.OESmilesToMol(mol, smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() assert len(f.fragments) == len(f.rotors_wbo) assert f.fragments.keys() == f.rotors_wbo.keys()
def test_2D_conformation(self): """Test checking for 2D conformation""" from fragmenter import chemi, states mol = chemi.smiles_to_oemol('CCCC') states = states.enumerate_states(mol, return_mols=True) for state in states: self.assertFalse(chemi.has_conformer(state, check_two_dimension=True)) conf = chemi.generate_conformers(mol, max_confs=1) self.assertTrue(chemi.has_conformer(conf, check_two_dimension=True))
def test_has_conformer(self): """Test has conformer""" infile = get_fn('butane.pdb') ifs = oechem.oemolistream(infile) molecule_with_conf = oechem.OEMol() oechem.OEReadMolecule(ifs, molecule_with_conf) self.assertTrue(chemi.has_conformer(molecule_with_conf)) molecule_without_conf = chemi.smiles_to_oemol('CCCC') self.assertFalse(chemi.has_conformer(molecule_without_conf))
def test_atom_map_order(self): """Test atom map""" from openeye import oechem tagged_smiles = '[H:5][C:1]#[N+:4][C:3]([H:9])([H:10])[C:2]([H:6])([H:7])[H:8]' mol_from_tagged_smiles = chemi.smiles_to_oemol(tagged_smiles) atom_map = get_atom_map(mol_from_tagged_smiles, tagged_smiles) # Compare atom map to tag for i in range(1, len(atom_map) + 1): atom_1 = mol_from_tagged_smiles.GetAtom( oechem.OEHasAtomIdx(atom_map[i])) self.assertEqual(i, atom_1.GetMapIdx())
def test_calculate_wbo(): smiles = 'CCCC' oemol = chemi.smiles_to_oemol(smiles, name='butane') f = fragmenter.fragment.WBOFragmenter(oemol) mol = f.calculate_wbo() assert not mol for bond in f.molecule.GetBonds(): assert 'WibergBondOrder' in bond.GetData() mol = f.calculate_wbo(f.molecule) assert mol for bond in mol.GetBonds(): assert 'WibergBondOrder' in bond.GetData()
def test_to_qcscheme_mol(): smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.fragment() qcschema_mol = f._to_qcschema_mol(f.fragments[(3, 5)]) assert 'initial_molecule' in qcschema_mol assert 'geometry' in qcschema_mol['initial_molecule'][0] assert 'symbols' in qcschema_mol['initial_molecule'][0] assert 'connectivity' in qcschema_mol['initial_molecule'][0] assert 'identifiers' in qcschema_mol assert 'provenance' in qcschema_mol
def test_build_fragment(): from openeye import oechem smiles = 'CCCCCC' mol = chemi.smiles_to_oemol(smiles) f = fragmenter.fragment.WBOFragmenter(mol) f.calculate_wbo() f._get_rotor_wbo() setattr(f, 'threshold', 0.05) for bond in f.rotors_wbo: f._build_fragment(bond) assert len(f.fragments) == 3 for bond in f.fragments: remove_atom_map(f.fragments[bond]) assert oechem.OEMolToSmiles(f.fragments[bond]) == 'CCCC'
def test_atom_map(self): """Test get atom map""" from openeye import oechem tagged_smiles = '[H:5][C:1]#[N+:4][C:3]([H:9])([H:10])[C:2]([H:6])([H:7])[H:8]' mol_1 = chemi.smiles_to_oemol('CC[N+]#C') inf = get_fn('ethylmethylidyneamonium.mol2') ifs = oechem.oemolistream(inf) mol_2 = oechem.OEMol() oechem.OEReadMolecule(ifs, mol_2) atom_map = get_atom_map(mol_1, tagged_smiles) for i, mapping in enumerate(atom_map): atom_1 = mol_1.GetAtom(oechem.OEHasAtomIdx(atom_map[mapping])) atom_1.SetAtomicNum(i + 1) atom_2 = mol_2.GetAtom(oechem.OEHasAtomIdx(mapping - 1)) atom_2.SetAtomicNum(i + 1) self.assertEqual(oechem.OECreateCanSmiString(mol_1), oechem.OECreateCanSmiString(mol_2)) # Test aromatic molecule tagged_smiles = '[H:10][c:4]1[c:3]([c:2]([c:1]([c:6]([c:5]1[H:11])[H:12])[C:7]([H:13])([H:14])[H:15])[H:8])[H:9]' mol_1 = chemi.smiles_to_oemol('Cc1ccccc1') inf = get_fn('toluene.mol2') ifs = oechem.oemolistream(inf) mol_2 = oechem.OEMol() oechem.OEReadMolecule(ifs, mol_2) atom_map = get_atom_map(mol_1, tagged_smiles) for i, mapping in enumerate(atom_map): atom_1 = mol_1.GetAtom(oechem.OEHasAtomIdx(atom_map[mapping])) atom_1.SetAtomicNum(i + 1) atom_2 = mol_2.GetAtom(oechem.OEHasAtomIdx(mapping - 1)) atom_2.SetAtomicNum(i + 1) self.assertEqual(oechem.OECreateCanSmiString(mol_1), oechem.OECreateCanSmiString(mol_2))
def test_mapped_xyz(self): """Test writing out mapped xyz""" from openeye import oechem, oeomega tagged_smiles = '[H:10][c:4]1[c:3]([c:2]([c:1]([c:6]([c:5]1[H:11])[H:12])[C:7]([H:13])([H:14])[H:15])[H:8])[H:9]' mol_1 = chemi.smiles_to_oemol('Cc1ccccc1') inf = get_fn('toluene.mol2') ifs = oechem.oemolistream(inf) mol_2 = oechem.OEMol() oechem.OEReadMolecule(ifs, mol_2) mol_1 = chemi.generate_conformers(mol_1, max_confs=1) atom_map = get_atom_map(mol_1, tagged_smiles) for i, mapping in enumerate(atom_map): atom_1 = mol_1.GetAtom(oechem.OEHasAtomIdx(atom_map[mapping])) atom_1.SetAtomicNum(i + 1) atom_2 = mol_2.GetAtom(oechem.OEHasAtomIdx(mapping - 1)) atom_2.SetAtomicNum(i + 1) xyz_1 = chemi.to_mapped_xyz(mol_1, atom_map, xyz_format=False) # molecule generated from mol2 should be in the right order. atom_map_mol2 = { 1: 0, 2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 7, 9: 8, 10: 9, 11: 10, 12: 11, 13: 12, 14: 13, 15: 14 } xyz_2 = chemi.to_mapped_xyz(mol_2, atom_map_mol2, xyz_format=False) for ele1, ele2 in zip(xyz_1.split('\n')[:-1], xyz_2.split('\n')[:-1]): self.assertEqual(ele1.split(' ')[2], ele2.split(' ')[2])
def enumerate_fragments(molecule, title='', mol_provenance=None, json_filename=None, generate_vis=True): """ Fragment molecule Parameters ---------- molecule: Input molecule. Very permissive. Can be anything that OpenEye can parse SMILES string of molecule to fragment title: str, optional. Default empty str The title or name of the molecule. If empty stirng will use the IUPAC name for molecule title. mol_provenance: dict, optional. Default is None provenance for molecule. If the molecule is a state from enumerate_states, the provenance from enumerate_states should be used json_filename: str, optional. Default None If a filename is provided, will write output to json file. generate_vis: bool, optional, default False If True, will generate visualization of fragments from parent molecule """ parent_molecule = chemi.smiles_to_oemol(molecule, name=title) fragment_engine = fragment.CombinatorialFragmenter(parent_molecule, functional_groups=False) fragment_engine.fragment() frag_json = fragment_engine.to_json() with open(json_filename, 'w') as f: json.dump(frag_json, f, indent=2, sort_keys=True) if len(fragment_engine.new_stereo) > 0: # Save fragments that are missing stereo because of new stereo center chemi.smiles_to_smi(fragment_engine.new_stereo, filename='{}_new_stereo_missing.smi'.format(title)) if generate_vis: fname = '{}.pdf'.format(parent_molecule.GetTitle()) fragment_engine.depict_fragments(fname=fname)
def test_expand_enantiomers(self): smiles = 'CN(C)C/C=C/C(=O)NC1=C(C=C2C(=C1)C(=NC=N2)NC3=CC(=C(C=C3)F)Cl)O[C@H]4CCOC4' molecule = chemi.smiles_to_oemol(smiles) stereoisomers = fragmenter.fragment._expand_states( molecule, enumerate='stereoisomers') stereoisomers_1 = { 'CN(C)C/C=C/C(=O)Nc1cc2c(cc1O[C@@H]3CCOC3)ncnc2Nc4ccc(c(c4)Cl)F', 'CN(C)C/C=C/C(=O)Nc1cc2c(cc1O[C@H]3CCOC3)ncnc2Nc4ccc(c(c4)Cl)F', 'CN(C)C/C=C\\C(=O)Nc1cc2c(cc1O[C@@H]3CCOC3)ncnc2Nc4ccc(c(c4)Cl)F', 'CN(C)C/C=C\\C(=O)Nc1cc2c(cc1O[C@H]3CCOC3)ncnc2Nc4ccc(c(c4)Cl)F' } stereoisomers_2 = set() for mol in stereoisomers: stereoisomers_2.add( mol_to_smiles(mol, mapped=False, explicit_hydrogen=False, isomeric=True)) intersection = stereoisomers_1.intersection(stereoisomers_2) self.assertEqual(len(intersection), len(stereoisomers_1)) self.assertEqual(len(intersection), len(stereoisomers_2)) self.assertEqual(len(stereoisomers_1), len(stereoisomers_2))
def test_find_torsion_around_bond(): mol = chemi.smiles_to_oemol('CCCC', add_atom_map=True) dihedral = torsions.find_torsion_around_bond(mol, (3, 4)) assert dihedral == [0, 2, 3, 1]
def mapped_molecule(): return chemi.smiles_to_oemol( '[H:5][C:1]([H:6])([H:7])[C:3]([H:11])([H:12])[C:4]([H:13])([H:14])[C:2]([H:8])([H:9])[H:10]' )
def test_pfizer_fragmenter(input, output): mol = chemi.smiles_to_oemol(input) f = fragmenter.fragment.PfizerFragmenter(mol) f.fragment() assert len(f.fragments) == output