예제 #1
0
def _apply_forward_reaction(template_row: pd.Series,
                            config: Config) -> Optional[pd.DataFrame]:
    smarts_fwd = reverse_template(template_row.retro_template)
    mols = create_reactants_molecules(template_row.reactants)

    try:
        ref_mol = Molecule(smiles=template_row.products, sanitize=True)
    except MoleculeException as err:
        raise _ReactionException(
            f"reaction {template_row.reaction_hash} failed with msg {str(err)}"
        )

    try:
        products = Reaction(mols=mols, smarts=smarts_fwd).apply()
    except ValueError as err:
        raise _ReactionException(
            f"reaction {template_row.reaction_hash} failed with msg {str(err)}"
        )

    new_products = {
        product[0]
        for product in products if product[0] != ref_mol
    }
    if not new_products:
        return None

    correct_products = {
        product[0]
        for product in products if product[0].basic_compare(ref_mol)
    }
    if not correct_products:
        raise _ReactionException(
            f"reaction {template_row.reaction_hash} failed to produce correct product"
        )

    return _new_dataframe(
        template_row,
        config,
        nrows=len(new_products),
        reaction_hash=[
            reaction_hash(template_row.reactants, product)
            for product in new_products
        ],
        products=[product.smiles for product in new_products],
    )
예제 #2
0
def _sample_library(library: pd.DataFrame, config: Config,
                    sampler_func: Callable) -> _DfGenerator:
    for _, row in library.iterrows():
        mols = create_reactants_molecules(row.reactants)
        try:
            ref_mol = Molecule(smiles=row.products, sanitize=True)
        except MoleculeException:
            yield None
            continue

        new_product = None
        for template_row in sampler_func(row):
            if row.template_hash == template_row.template_hash:
                continue
            smarts_fwd = reverse_template(template_row.retro_template)
            try:
                new_product = Reaction(mols=mols,
                                       smarts=smarts_fwd).apply()[0][0]
            except (ValueError, IndexError):
                continue
            if new_product.basic_compare(ref_mol):
                continue
            break  # If we have reached here, we have found a match that fits all criteria

        if not new_product:
            yield None
            continue

        # pylint: disable=undefined-loop-variable
        yield _new_dataframe(
            row,
            config,
            reaction_hash=[reaction_hash(row.reactants, new_product)],
            products=[new_product.smiles],
            classification=[""],
            retro_template=[template_row.retro_template],
            template_hash=[template_row.template_hash],
            selectivity=[0],
            outcomes=[1],
            template_code=[template_row.template_code],
        )
예제 #3
0
def test_reverse_template():
    retro_template = "([C:2]-[C:3](=[O;D1;H0:4])-[N;H0;D3;+0:5](-[CH3;D1;+0:1])-[c:6])>>(I-[CH3;D1;+0:1]).([C:2]-[C:3](=[O;D1;H0:4])-[NH;D2;+0:5]-[c:6])"  # noqa
    expected = "(I-[CH3;D1;+0:1]).([C:2]-[C:3](=[O;D1;H0:4])-[NH;D2;+0:5]-[c:6])>>([C:2]-[C:3](=[O;D1;H0:4])-[N;H0;D3;+0:5](-[CH3;D1;+0:1])-[c:6])"  # noqa

    assert reverse_template(retro_template) == expected