Skip to content

Commit 67f8a69

Browse files
committed
better error handling for O3DAlign
1 parent 32ac152 commit 67f8a69

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

src/python/pipelines/rdkit/o3dAlign.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,17 @@
2727

2828
field_O3DAScore = "O3DAScore"
2929

30-
### start function defintions #########################################
30+
### start function definitions #########################################
3131

3232
def doO3Dalign(i, mol, qmol, threshold, perfect_score, writer, conformerProps=None, minEnergy=None):
3333
pyO3As = rdMolAlign.GetO3AForProbeConfs(mol, qmol)
34+
if len(pyO3As) == 0:
35+
return 0
36+
3437
best_score = 0
3538
j = 0
3639
conf_id = -1
40+
3741
for pyO3A in pyO3As:
3842
align = pyO3A.Align()
3943
score = pyO3A.Score()
@@ -44,7 +48,7 @@ def doO3Dalign(i, mol, qmol, threshold, perfect_score, writer, conformerProps=No
4448

4549
#utils.log("Best score = ",best_score)
4650
if not threshold or perfect_score - best_score < threshold:
47-
utils.log(i, align, score, Chem.MolToSmiles(mol, isomericSmiles=True))
51+
utils.log("Molecule", i, align, score)
4852
mol.SetDoubleProp(field_O3DAScore, score)
4953
if conformerProps and minEnergy:
5054
eAbs = conformerProps[conf_id][(conformers.field_EnergyAbs)]
@@ -68,12 +72,15 @@ def main():
6872
parser.add_argument('-n', '--num', default=0, type=int, help='number of conformers to generate, if None then input structures are assumed to already be 3D')
6973
parser.add_argument('-a', '--attempts', default=0, type=int, help='number of attempts to generate conformers')
7074
parser.add_argument('-r', '--rmsd', type=float, default=1.0, help='prune RMSD threshold for excluding conformers')
71-
parser.add_argument('-e', '--emin', type=int, default=0, help='energy minimisation iterations for generated confomers (default of 0 means none)')
75+
parser.add_argument('-e', '--emin', type=int, default=0, help='energy minimisation iterations for generated conformers (default of 0 means none)')
7276
parameter_utils.add_default_io_args(parser)
7377

7478
args = parser.parse_args()
7579
utils.log("o3dAlign Args: ", args)
7680

81+
# TODO - handle molecules with multiple fragments
82+
# TODO - allow to specify threshold as fraction of perfect score?
83+
7784
qmol = rdkit_utils.read_single_molecule(args.query, index=args.qmolidx)
7885
qmol = Chem.RemoveHs(qmol)
7986
qmol2 = Chem.Mol(qmol)
@@ -107,26 +114,33 @@ def main():
107114
i=0
108115
count = 0
109116
total = 0
117+
errors = 0
110118
for mol in suppl:
111-
if mol is None: continue
112-
if args.num > 0:
113-
mol.RemoveAllConformers()
114-
conformerProps, minEnergy = conformers.process_mol_conformers(mol, i, args.num, args.attempts, args.rmsd, None, None, 0)
115-
mol = Chem.RemoveHs(mol)
116-
count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer, conformerProps=conformerProps, minEnergy=minEnergy)
117-
else:
118-
mol = Chem.RemoveHs(mol)
119-
count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer)
119+
if mol is None:
120+
i +=1
121+
continue
122+
try:
123+
if args.num > 0:
124+
mol.RemoveAllConformers()
125+
conformerProps, minEnergy = conformers.process_mol_conformers(mol, i, args.num, args.attempts, args.rmsd, None, None, 0)
126+
mol = Chem.RemoveHs(mol)
127+
count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer, conformerProps=conformerProps, minEnergy=minEnergy)
128+
else:
129+
mol = Chem.RemoveHs(mol)
130+
count += doO3Dalign(i, mol, qmol, args.threshold, perfect_score, writer)
131+
total += mol.GetNumConformers()
132+
except ValueError as e:
133+
errors +=1
134+
utils.log("Molecule", i, "failed to align:", e.message)
120135
i +=1
121-
total += mol.GetNumConformers()
122-
136+
123137
input.close()
124138
writer.flush()
125139
writer.close()
126140
output.close()
127141

128142
if args.meta:
129-
utils.write_metrics(output_base, {'__InputCount__':i, '__OutputCount__':count, 'RDKitO3DAlign':total})
143+
utils.write_metrics(output_base, {'__InputCount__':i, '__OutputCount__':count, '__ErrorCount__':errors, 'RDKitO3DAlign':total})
130144

131145
if __name__ == "__main__":
132146
main()

0 commit comments

Comments
 (0)