connorcoley / rdchiral

Wrapper for RDKit's RunReactants to improve stereochemistry handling
MIT License
151 stars 50 forks source link

A reaction case could not be extracted templates successfully. #42

Closed queliyong closed 1 year ago

queliyong commented 1 year ago

Hi, This reaction could not be extracted template. There is no result when I used 'rdc.rdchiralRun'. Thank u very much. CC(C)CC(CC(OCC)=O)CC(OCC)=O>>CC(C)C[C@H](CC(OCC)=O)CC(O)=O

connorcoley commented 1 year ago

At least at present, RDChiral requires atom mapped reaction SMILES

queliyong commented 1 year ago

Very sorry for my negligence. I tried this reaction SMILES atom mapped by RXNMapper, but it could not be extracted template successfully, so I submit it to u to seek for the reason why it fails. CC[O:11][C:9]([CH2:8][CH:7]([CH2:6][C:4]([O:3][CH2:2][CH3:1])=[O:5])[CH2:12][CH:13]([CH3:14])[CH3:15])=[O:10]>>[CH3:1][CH2:2][O:3][C:4](=[O:5])[CH2:6][C@H:7]([CH2:8][C:9](=[O:10])[OH:11])[CH2:12][CH:13]([CH3:14])[CH3:15] F1A9E5D6-FE4C-4015-BD00-D9D7B67C13B3

connorcoley commented 1 year ago

I do not have a problem extracting the template from this reaction:

{'products': '[O;D1;H0:3]=[C:2]-[OH;D1;+0:1]', 'reactants': 'C-C-[O;H0;D2;+0:1]-[C:2]=[O;D1;H0:3]', 'reaction_smarts': '[O;D1;H0:3]=[C:2]-[OH;D1;+0:1]>>C-C-[O;H0;D2;+0:1]-[C:2]=[O;D1;H0:3]', 'intra_only': True, 'dimer_only': False, 'reaction_id': 0, 'necessary_reagent': ''}
from rdchiral import template_extractor
rxn = {'reactants': 'CC[O:11][C:9]([CH2:8][CH:7]([CH2:6][C:4]([O:3][CH2:2][CH3:1])=[O:5])[CH2:12][CH:13]([CH3:14])[CH3:15])=[O:10]', 'products': '[CH3:1][CH2:2][O:3][C:4](=[O:5])[CH2:6][C@H:7]([CH2:8][C:9](=[O:10])[OH:11])[CH2:12][CH:13]([CH3:14])[CH3:15]', '_id': 0}
template_extractor.extract_from_reaction(rxn)
queliyong commented 1 year ago

I do not have a problem extracting the template from this reaction:

{'products': '[O;D1;H0:3]=[C:2]-[OH;D1;+0:1]', 'reactants': 'C-C-[O;H0;D2;+0:1]-[C:2]=[O;D1;H0:3]', 'reaction_smarts': '[O;D1;H0:3]=[C:2]-[OH;D1;+0:1]>>C-C-[O;H0;D2;+0:1]-[C:2]=[O;D1;H0:3]', 'intra_only': True, 'dimer_only': False, 'reaction_id': 0, 'necessary_reagent': ''}
from rdchiral import template_extractor
rxn = {'reactants': 'CC[O:11][C:9]([CH2:8][CH:7]([CH2:6][C:4]([O:3][CH2:2][CH3:1])=[O:5])[CH2:12][CH:13]([CH3:14])[CH3:15])=[O:10]', 'products': '[CH3:1][CH2:2][O:3][C:4](=[O:5])[CH2:6][C@H:7]([CH2:8][C:9](=[O:10])[OH:11])[CH2:12][CH:13]([CH3:14])[CH3:15]', '_id': 0}
template_extractor.extract_from_reaction(rxn)

Thanks a lot for your prompt response. Although there is a template extracted by "template_extractor.extract_from_reaction", there is no result when I used 'rdc.rdchiralRun', and even if I tried many different radius to extract more specific template, it fails to generate any reactants either. The code is below: from rdchiral import main as rdc reaction = rdc.rdchiralReaction('[O;D1;H0:3]=[C:2]-[OH;D1;+0:1]>>C-C-[O;H0;D2;+0:1]-[C:2]=[O;D1;H0:3]') rct = rdc.rdchiralReactants('CC(C)C[C@H](CC(OCC)=O)CC(O)=O') reactants = rdc.rdchiralRun(reaction, rct)

connorcoley commented 1 year ago

I see now. There must be a bug for this particular case where the retrosynthetic precursor that is generated gains symmetry, thereby making the previously chiral carbon achiral. If you increase the verbosity in rdchiral.utils, you get the following error:

After attempting to re-introduce chirality, outcome = [CH3:1][CH2:2][O:3][C:4](=[O:5])[CH2:6][C@H:7]([CH2:8][C:9](=[O:10])[O:11][CH2:901][CH3:900])[CH2:12][CH:13]([CH3:14])[CH3:15]
Auxiliary reactant atom was chiral, now is broken -> skip outcome

In your case, the desired behavior would likely involve modifying rdchiral/main.py to not just check if the chiral tag is unspecified (L508), but to check whether it's even possible to set the chiral tag given symmetry in the generated structures. I would need to think about whether that is always the desired functionality, but you could temporarily remove this check for your use case

queliyong commented 1 year ago

Thanks for your advice. I am trying to debug this for my convenience. Since RDKit has no function to check symmetry directly, I check it indirectly by a custom function below: BB87F8E6-DB33-4973-ADBB-C53249421918

I tested this function, and it works. Any suggestion would be appreciated. The source code I modified is below:

skip_outcome = False
if len(tetra_copied_from_reactants) > 0:
    Chem.AssignStereochemistry(outcome, cleanIt=True, force=True)
    for a in tetra_copied_from_reactants:
        if a.GetChiralTag() == ChiralType.CHI_UNSPECIFIED:
            if not check_symmetry(outcome, a.GetIdx()):
                if PLEVEL >= 2: print('Auxiliary reactant atom was chiral, now is broken -> skip outcome')
                skip_outcome = True
                break
if skip_outcome:
    continue
queliyong commented 1 year ago

Sorry for pasting a picture above due to its bad edit functionality.

connorcoley commented 1 year ago

What you've proposed seems okay as a workaround; a more direct fix would likely involve calling CanonicalRankAtoms with breakTies=False, then checking the neighbors of an sp3 carbon center to see if they are all unique and if the number of neighbors is 3 or 4.

queliyong commented 1 year ago

Thanks again for your guidance.