1
1
import os .path
2
+
2
3
from rdkit import Chem
3
- from rdkit .Chem .rdchem import RWMol , Conformer
4
- from rdkit .Chem .rdmolfiles import MolFromMol2File , MolFromSmarts
5
4
from rdkit .Chem .AllChem import ConstrainedEmbed
5
+ from rdkit .Chem .rdchem import Conformer , RWMol
6
6
from rdkit .Chem .rdChemReactions import ReactionFromSmarts
7
+ from rdkit .Chem .rdmolfiles import MolFromMol2File , MolFromSmarts
7
8
from rdkit .Chem .rdmolops import RemoveStereochemistry
8
9
9
- def make_bonds_dative (mol , target_elem = "Ir" ):
10
+
11
+ def make_bonds_dative (mol , target_elem = "Ir" ):
10
12
editable_mol = RWMol (mol )
11
13
12
14
# If you don't make a list, it loops infinitely over the bonds it's creating
13
15
for bond in list (editable_mol .GetBonds ()):
14
16
iridium = None
15
17
nitrogen = None
16
18
carbene = None
17
- if bond .GetBeginAtom ().GetSymbol () == target_elem and \
18
- bond .GetEndAtom ().GetSymbol () in ["N" , "P" ] and \
19
- bond .GetEndAtom ().GetFormalCharge () == 1 :
19
+ if (
20
+ bond .GetBeginAtom ().GetSymbol () == target_elem
21
+ and bond .GetEndAtom ().GetSymbol () in ["N" , "P" ]
22
+ and bond .GetEndAtom ().GetFormalCharge () == 1
23
+ ):
20
24
iridium = bond .GetBeginAtom ()
21
25
nitrogen = bond .GetEndAtom ()
22
26
start_idx = bond .GetEndAtomIdx ()
23
27
end_idx = bond .GetBeginAtomIdx ()
24
- elif bond .GetEndAtom ().GetSymbol () == target_elem and \
25
- bond .GetBeginAtom ().GetSymbol () in ["N" , "P" ] and \
26
- bond .GetBeginAtom ().GetFormalCharge () == 1 :
28
+ elif (
29
+ bond .GetEndAtom ().GetSymbol () == target_elem
30
+ and bond .GetBeginAtom ().GetSymbol () in ["N" , "P" ]
31
+ and bond .GetBeginAtom ().GetFormalCharge () == 1
32
+ ):
27
33
iridium = bond .GetEndAtom ()
28
34
nitrogen = bond .GetBeginAtom ()
29
35
start_idx = bond .GetBeginAtomIdx ()
30
36
end_idx = bond .GetEndAtomIdx ()
31
- if bond .GetBeginAtom ().GetSymbol () == target_elem and \
32
- bond .GetEndAtom ().GetSymbol () == "C" and \
33
- bond .GetEndAtom ().GetTotalValence () == 3 :
37
+ if (
38
+ bond .GetBeginAtom ().GetSymbol () == target_elem
39
+ and bond .GetEndAtom ().GetSymbol () == "C"
40
+ and bond .GetEndAtom ().GetTotalValence () == 3
41
+ ):
34
42
iridium = bond .GetBeginAtom ()
35
43
carbene = bond .GetEndAtom ()
36
44
start_idx = bond .GetEndAtomIdx ()
37
45
end_idx = bond .GetBeginAtomIdx ()
38
- elif bond .GetEndAtom ().GetSymbol () == target_elem and \
39
- bond .GetBeginAtom ().GetSymbol () == "C" and \
40
- bond .GetBeginAtom ().GetTotalValence () == 3 :
46
+ elif (
47
+ bond .GetEndAtom ().GetSymbol () == target_elem
48
+ and bond .GetBeginAtom ().GetSymbol () == "C"
49
+ and bond .GetBeginAtom ().GetTotalValence () == 3
50
+ ):
41
51
iridium = bond .GetEndAtom ()
42
52
carbene = bond .GetBeginAtom ()
43
53
start_idx = bond .GetBeginAtomIdx ()
@@ -56,17 +66,19 @@ def make_bonds_dative(mol, target_elem = "Ir"):
56
66
57
67
return outmol
58
68
59
- def transfer_conformation (mol , substruct , conformer = 0 ):
60
- '''Given a molecule, and a second molecule which is a substructure of the
69
+
70
+ def transfer_conformation (mol , substruct , conformer = 0 ):
71
+ """Given a molecule, and a second molecule which is a substructure of the
61
72
first, assign coordinates to the substructure based on the matching part of
62
- the original molecule'''
73
+ the original molecule"""
63
74
match = mol .GetSubstructMatch (substruct )
64
75
substruct_conformation = Conformer (substruct .GetNumAtoms ())
65
76
for i , index in enumerate (match ):
66
77
point = mol .GetConformer (conformer ).GetAtomPosition (index )
67
78
substruct_conformation .SetAtomPosition (i , point )
68
79
substruct .AddConformer (substruct_conformation )
69
80
81
+
70
82
fac = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "OHUZEW.mol2" )))
71
83
RemoveStereochemistry (fac )
72
84
mer = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "OHUZIA.mol2" )))
@@ -79,6 +91,7 @@ def transfer_conformation(mol, substruct, conformer = 0):
79
91
carbene_mer = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "MAXYOA.mol2" )))
80
92
RemoveStereochemistry (carbene_mer )
81
93
94
+
82
95
# Extract skeletons of a molecule based on a template, keeping coordinates
83
96
# Multiple skeletons because I don't know how to do wildcards
84
97
def skeleton (template , mol ):
@@ -96,50 +109,69 @@ def skeleton(template, mol):
96
109
skeleton_mol = editable_mol .GetMol ()
97
110
return skeleton_mol
98
111
112
+
99
113
fac_skeleton = skeleton (template , fac )
100
114
mer_skeleton = skeleton (template , mer )
101
115
102
116
# Making the carbene skeletons in a completely different way
103
117
# I probably am going to want to do this for all of them
104
- carbene_skeleton_smarts = "[Ir]135(<-[CH0](~N(~*)~*~2)~N(~*~2)~c~c~1)(<-[CH0](~N(~*)~*~4)~N(~*~4)~c~c~3)(<-[CH0](~N(~*)~*~6)~N(~*~6)~c~c~5)"
118
+ carbene_skeleton_smarts = (
119
+ "[Ir]135(<-[CH0](~N(~*)~*~2)~N(~*~2)~c~c~1)(<-[CH0](~N(~*)~*~4)~N(~*~4)~c~c~3)(<-[CH0](~N(~*)~*~6)~N(~*~6)~c~c~5)"
120
+ )
105
121
carbene_fac_skeleton = MolFromSmarts (carbene_skeleton_smarts )
106
122
transfer_conformation (carbene_fac , carbene_fac_skeleton )
107
123
carbene_mer_skeleton = MolFromSmarts (carbene_skeleton_smarts )
108
124
transfer_conformation (carbene_mer , carbene_mer_skeleton )
109
125
126
+
110
127
def run_three_times (mol , reaction ):
111
128
for i in range (3 ):
112
129
mol = reaction .RunReactants ([mol ])[0 ][0 ]
113
130
return mol
131
+
132
+
114
133
reactions = [
115
134
ReactionFromSmarts ("[Ir:1]1<-[n:2]:[n:3]~[c:4]:[c:5]~1>>[Ir:1]1<-[n:2]:[c:3]~[n:4]:[c:5]~1" ),
116
135
ReactionFromSmarts ("[Ir:1]1<-[n:2]:[n:3]~[c:4]:[c:5]~1>>[Ir:1]1<-[n:2]:[n:3]~[n:4]:[c:5]~1" ),
117
- ReactionFromSmarts ("[Ir:1]1<-[n:2]:[n:3]~[c:4]:[c:5]~1>>[Ir:1]1<-[n:2]:[c:3]~[c:4]:[c:5]~1" )
136
+ ReactionFromSmarts ("[Ir:1]1<-[n:2]:[n:3]~[c:4]:[c:5]~1>>[Ir:1]1<-[n:2]:[c:3]~[c:4]:[c:5]~1" ),
118
137
]
119
- fac_skeletons = [fac_skeleton ] + [run_three_times (fac_skeleton , reaction ) for reaction in reactions ] + [carbene_fac_skeleton ]
120
- mer_skeletons = [mer_skeleton ] + [run_three_times (mer_skeleton , reaction ) for reaction in reactions ] + [carbene_mer_skeleton ]
138
+ fac_skeletons = (
139
+ [fac_skeleton ] + [run_three_times (fac_skeleton , reaction ) for reaction in reactions ] + [carbene_fac_skeleton ]
140
+ )
141
+ mer_skeletons = (
142
+ [mer_skeleton ] + [run_three_times (mer_skeleton , reaction ) for reaction in reactions ] + [carbene_mer_skeleton ]
143
+ )
121
144
122
145
# Skeletons for tridentate carbenes
123
146
# I may have to remake these later if I want to control the isomers
124
147
# For now I think it doesn't matter because all the carbene ligands are symmetric?
125
148
# For homoleptic:
126
149
biplet = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "BIPLET.mol2" )))
127
- biplet_skeleton = MolFromSmarts ('[Ir]1234(~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~1~c~[#7]~[#6](~[#7](~[#6])~[#6])~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4' )
150
+ biplet_skeleton = MolFromSmarts (
151
+ "[Ir]1234(~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~1~c~[#7]~[#6](~[#7](~[#6])~[#6])~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4"
152
+ )
128
153
transfer_conformation (biplet , biplet_skeleton )
129
154
# For heteroleptic, three with counterligands of different size
130
155
soynom = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "SOYNOM.mol2" )))
131
156
RemoveStereochemistry (soynom )
132
- soynom_skeleton = MolFromSmarts ('[Ir]1234(~*~*~*~*~1~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4' )
157
+ soynom_skeleton = MolFromSmarts (
158
+ "[Ir]1234(~*~*~*~*~1~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4"
159
+ )
133
160
transfer_conformation (soynom , soynom_skeleton )
134
161
uyokur = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "UYOKUR.mol2" )))
135
- uyokur_skeleton = MolFromSmarts ('[Ir]1234(~*~*~*~*~*~1~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4' )
162
+ uyokur_skeleton = MolFromSmarts (
163
+ "[Ir]1234(~*~*~*~*~*~1~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4"
164
+ )
136
165
transfer_conformation (uyokur , uyokur_skeleton )
137
166
egufiz = make_bonds_dative (MolFromMol2File (os .path .join (__path__ [0 ], "EGUFIZ.mol2" )))
138
- egufiz_skeleton = MolFromSmarts ('[Ir]1234(~*~*~*~*~*~1~*~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4' )
167
+ egufiz_skeleton = MolFromSmarts (
168
+ "[Ir]1234(~*~*~*~*~*~1~*~*~*~*~2)~[#6](~[#7](~[#6])~[#6])~[#7]~c~c~3~c~[#7]~[#6](~[#7](~[#6])~[#6])~4"
169
+ )
139
170
transfer_conformation (egufiz , egufiz_skeleton )
140
171
# Homoleptic has to go first, since a later pattern can cover it
141
172
tridentate_skeletons = [biplet_skeleton , soynom_skeleton , uyokur_skeleton , egufiz_skeleton ]
142
173
174
+
143
175
def octahedral_embed (mol , isomer ):
144
176
# Needed for some of the mol2 files I got from CSD
145
177
# Will not be able to embed with stereochemistry
@@ -151,7 +183,7 @@ def octahedral_embed(mol, isomer):
151
183
elif isomer == "tridentate" :
152
184
skeletons = tridentate_skeletons
153
185
else :
154
- raise ValueError (f" Isomer should be \ " mer\ " or \ " fac\ " , given { isomer } " )
186
+ raise ValueError (f' Isomer should be "mer" or "fac", given { isomer } ' )
155
187
finished = False
156
188
for skeleton in skeletons :
157
189
if len (mol .GetSubstructMatch (skeleton )) > 0 :
@@ -160,7 +192,7 @@ def octahedral_embed(mol, isomer):
160
192
# with a small template the imidazole is hroribly twisted, probably
161
193
# because it thinks the atoms are aliphatic. Ignoring smoothing
162
194
# failures with the large template, it works
163
- ConstrainedEmbed (mol , skeleton , ignoreSmoothingFailures = True )
195
+ ConstrainedEmbed (mol , skeleton , ignoreSmoothingFailures = True )
164
196
finished = True
165
197
if not finished :
166
198
raise ValueError ("Doesn't match templates" )
0 commit comments