{"id":10688,"date":"2024-01-02T13:08:43","date_gmt":"2024-01-02T13:08:43","guid":{"rendered":"https:\/\/www.blopig.com\/blog\/?p=10688"},"modified":"2024-04-18T09:45:57","modified_gmt":"2024-04-18T08:45:57","slug":"finding-and-testing-a-reaction-smarts-pattern-for-any-reaction","status":"publish","type":"post","link":"https:\/\/www.blopig.com\/blog\/2024\/01\/finding-and-testing-a-reaction-smarts-pattern-for-any-reaction\/","title":{"rendered":"Finding and testing a reaction SMARTS pattern for any reaction"},"content":{"rendered":"\n<p>Have you ever needed to find a reaction SMARTS pattern for a certain reaction but don&#8217;t have it already written out? Do you have a reaction SMARTS pattern but need to test it on a set of reactants and products to make sure it transforms them correctly and doesn&#8217;t allow for odd reactants to work? I recently did and I spent some time developing functions that can:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Generate a reaction SMARTS for a reaction given two reactants, a product, and a reaction name.<\/li>\n\n\n\n<li>Check the reaction SMARTS on a list of reactants and products that have the same reaction name.<\/li>\n<\/ol>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\">What is SMARTS?<\/h3>\n\n\n\n<p>SMARTS stands for SMiles ARbitrary Target Specification, and is a language used for pattern searching in molecules. It was invented by Daylight and they have much more information on their site <a href=\"https:\/\/www.daylight.com\/dayhtml_tutorials\/languages\/smarts\/smarts_examples.html#INTRO\" data-type=\"link\" data-id=\"https:\/\/www.daylight.com\/dayhtml_tutorials\/languages\/smarts\/smarts_examples.html#INTRO\">here<\/a>. Reaction SMARTS are SMARTS used to define reactions, they will usually have this basic structure:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[reactant_1].[reactant_N]&gt;&gt;[product_1].[product_N]<\/pre>\n\n\n\n<p>For the rest of the functions you&#8217;ll need to install and import the neccessary libraries.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">!pip install reaction-utils rxnmapper rdkit\n\nfrom rxnutils.chem.reaction import ChemicalReaction\nfrom rxnmapper import RXNMapper\nfrom rdkit import Chem\nfrom rdkit.Chem import AllChem, DataStructs, Draw<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Example 1:<\/strong> Generate a reaction SMARTS given the reactants and product<\/h2>\n\n\n\n<p>Let&#8217;s say we need a reaction smarts for the bimolecular reaction, reductive amination. I have these two reactants and product. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">reactant1 = Chem.MolFromSmiles('O=Cc1ccc2c(c1)OCO2')\nreactant2 = Chem.MolFromSmiles('Cc1nnc2c(N)nccn12')\nproduct = Chem.MolFromSmiles('Cc1nnc2c(NCc3ccc4c(c3)OCO4)nccn12')\ncaptions = ['Reactant 1', 'Reactant 2', 'Product']\nDraw.MolsToGridImage([reactant1, reactant2, product], molsPerRow=3, subImgSize=(300,300), legends=captions)<\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"208\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?resize=625%2C208&#038;ssl=1\" alt=\"\" class=\"wp-image-10727\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?w=900&amp;ssl=1 900w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?resize=300%2C100&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?resize=768%2C256&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/blog_1-1.png?resize=624%2C208&amp;ssl=1 624w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/figure>\n\n\n\n<p>Now lets define the <code>make_rxn_template<\/code> function, which takes the two reactant mol objects, product mol object, and radius for the reaction template search as inputs. The radius argument specifies the radius of the template. It uses <a href=\"https:\/\/github.com\/rxn4chemistry\/rxnmapper\">RXNmapper<\/a> which labels exact atoms in the reactants that are kept in the product. Steph (another lovely OPIG member) wrote a helpful post on this tool, <a href=\"https:\/\/www.blopig.com\/blog\/2023\/03\/atom-mapping-with-rxnmapper\/\" data-type=\"link\" data-id=\"https:\/\/www.blopig.com\/blog\/2023\/03\/atom-mapping-with-rxnmapper\/\">check it out<\/a>! <br><br>This <code>make_rxn_template<\/code> function outputs the SMARTS reaction template. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def make_rxn_template(reactants: list, product: Chem.Mol, radius=1):\n    \"\"\"\n    Given mol objects of two reactants and product, make a SMARTS reaction template.\n    \"\"\"\n    reactants = [Chem.MolToSmiles(reactant) for reactant in reactants]\n    product = Chem.MolToSmiles(product)\n    # Make string of reaction\n    reaction = f\"{reactants[0]}.{reactants[1]}&gt;&gt;{product}\"\n    rxnmapper = RXNMapper()\n    # Get atom mapped forward template\n    res = rxnmapper.get_attention_guided_atom_maps([reaction])[0]\n    # Convert to ChemicalReaction object\n    rxn = ChemicalReaction(res['mapped_rxn'])\n    # Get reaction templates with radius\n    mapping = rxn.generate_reaction_template(radius=radius, expand_ring=False, expand_hetero=False)\n    forward_template = mapping[0].smarts\n    return forward_template<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># create reaction SMARTS\nfirst_reductive_amination_mapping = make_rxn_template(reactants, product, radius=1)\nprint(first_reductive_amination_mapping)<\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>'O=&#091;CH;D2;+0:1]-&#091;c:2].&#091;#7;a:3]:&#091;c:4](-&#091;NH2;D1;+0:5]):&#091;c:6](:&#091;#7;a:7]):&#091;#7;a:8]&gt;&gt;&#091;#7;a:3]:&#091;c:4](-&#091;NH;D2;+0:5]-&#091;CH2;D2;+0:1]-&#091;c:2]):&#091;c:6](:&#091;#7;a:7]):&#091;#7;a:8]'<\/code><\/pre>\n\n\n\n<p>Great, that is our reaction SMARTS for reductive amination! To check if this reaction SMARTS will work for other reductive amination examples lets test it in Example 2. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 2: Check a reaction SMARTS on many reaction examples<\/h2>\n\n\n\n<p>Now we need to check if this SMARTS works for other examples of this same reaction in our dataset. I have a dataframe of 10 other reductive amination examples that looks like this:<\/p>\n\n\n\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right\">\n      <th>product<\/th>\n      <th>reactants<\/th>\n      <th>name<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>Cc1nnc2c(NCc3ccc4c(c3)OCO4)nccn12<\/td>\n      <td>(O=Cc1ccc2c(c1)OCO2, Cc1nnc2c(N)nccn12)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>O[C@@H](CNCc1nnc2ccccn12)c1ccc2c(c1)OCO2<\/td>\n      <td>(O=Cc1nnc2ccccn12, NCC(O)c1ccc2c(c1)OCO2)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>Cc1cc(C(=O)N[C@H](C)[C@H](C)NCc2ccccn2)no1<\/td>\n      <td>(O=Cc1ccccn1, Cc1cc(C(=O)NC(C)C(C)N)no1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>CCOC(=O)C[C@@H](c1cc(C)on1)N1CCCCC1<\/td>\n      <td>(CCOC(=O)CC(=O)c1cc(C)on1, C1CCNCC1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>C[C@@H](F)CCNC1CCN(C(=O)CCN2CCCCC2)CC1<\/td>\n      <td>(O=C1CCN(C(=O)CCN2CCCCC2)CC1, CC(F)CCN)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>c1cncc([C@@H]2CCC[C@@H](NCc3ccc4c(c3)OCO4)C2)c1<\/td>\n      <td>(O=C1CCCC(c2cccnc2)C1, NCc1ccc2c(c1)OCO2)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>COc1cccc(CN[C@H](Cc2ccc3c(c2)OCO3)C(=O)O)n1<\/td>\n      <td>(NC(Cc1ccc2c(c1)OCO2)C(=O)O, COc1cccc(C=O)n1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>Cc1cc(C(=O)NCC[C@@H](C)NCC(=O)N2CCCCC2)no1<\/td>\n      <td>(NCC(=O)N1CCCCC1, CC(=O)CCNC(=O)c1cc(C)on1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>FC(F)(F)C(F)(F)[C@@H]1CCCN(CCCN2CCCCC2)C1<\/td>\n      <td>(O=CCCN1CCCCC1, FC(F)(F)C(F)(F)C1CCCNC1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n    <tr>\n      <td>CC(C)(C)c1cncc(CN[C@@H](CN2CCCCC2)C(=O)O)c1<\/td>\n      <td>(NC(CN1CCCCC1)C(=O)O, CC(C)(C)c1cncc(C=O)c1)<\/td>\n      <td>Reductive_amination<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n\n<p>Here I define the following functions to test my generated reductive amination template  on my examples. Basically <code>check_smarts<\/code> is the entry function that takes the dataframe of the product and reactants as SMILES as input. For each row in the dataframe <code>check_rxn_template_works<\/code> applies the given reaction template to reactants and product using <code>check_rxn<\/code>. Both combinations of reactants are checked since the order is specific for each reaction template. <\/p>\n\n\n\n<p>The <code>check_rxn<\/code> function applies the reaction SMARTS to the reactants and if a product is found, that product is checked if it matches the original product by tanimoto similarity = 1. There are three possible outputs from <code>check_rxn<\/code>:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The reaction SMARTS is applicable and produces the expected product with Tanimoto similarity of 1.0.<\/li>\n\n\n\n<li>The reaction SMARTS is applicable but does not produce any of the expected products with Tanimoto similarity of 1.0.<\/li>\n\n\n\n<li>The reaction SMARTS is not applicable to the provided reactants, therefore there is no product. <\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\"\"\"\nThis code block contains functions for reaction enumeration and reaction mapping. NOTE: This is intended to be run in a jupyter notebook, hence the use of the display() functionality.\n\"\"\"\ndef remove_chirality(smiles: str):\n    return smiles.replace('@@', '').replace('@', '').replace('\/', '').replace('\\\\', '')\n\ndef check_rxn(rxn: AllChem.ChemicalReaction, reactants: list, products: list, verbose=False):\n    \"\"\"\n    Check if reaction template works for a combination of reactants\n    using Tanimoto similarity to compare against a list of products.\n    \n    INPUT:\n        rxn: AllChem.ReactionSmarts object\n        reactants: list of mol objects of reactants\n        products: list of smiles of possible products\n    \"\"\"\n    predicted_products_flat = []\n    if rxn.RunReactants(reactants):\n        predicted_products_list = rxn.RunReactants(reactants)\n        predicted_products_flat = [remove_chirality(Chem.MolToSmiles(mol)) for product_set in predicted_products_list for mol in product_set]\n        # Check Tanimoto similarity with each product in the provided list\n        for predicted_smiles in predicted_products_flat:\n            predicted_product_mol = Chem.MolFromSmiles(predicted_smiles)\n            predicted_product_fp = AllChem.GetMorganFingerprint(predicted_product_mol, 2)\n            for product_smiles in products:\n                product_mol = Chem.MolFromSmiles(product_smiles)\n                product_fp = AllChem.GetMorganFingerprint(product_mol, 2)\n                similarity = DataStructs.TanimotoSimilarity(product_fp, predicted_product_fp)\n                if similarity == 1.0:\n                    if verbose:\n                        print(\"The reaction SMARTS is applicable and produces the expected product with Tanimoto similarity of 1.0.\")\n                    return 1, predicted_products_flat\n        if verbose:\n            print(\"The reaction SMARTS is applicable but does not produce any of the expected products with Tanimoto similarity of 1.0.\")\n        return -1, predicted_products_flat\n    else:\n        if verbose:\n            print(\"The reaction SMARTS is not applicable to the provided reactants, therefore there is no product.\")\n        return 0, predicted_products_flat\n\ndef check_rxn_template_works(rxn_temp: str, reactants: list, products: list, verbose=False):\n    \"\"\"\n    Check if reaction template works. LOOKS AT BOTH COMBINATIONS OF REACTANTS.\n    \"\"\"\n    rxn = AllChem.ReactionFromSmarts(rxn_temp)\n    reactants = [Chem.MolFromSmiles(reactant) for reactant in reactants]\n    products = [remove_chirality(product) for product in products]\n    AllChem.SanitizeRxn(rxn)\n    outcome = 0\n    # Check if the number of reactants is applicable\n    if len(reactants) != len(rxn.GetReactants()):\n        if verbose: print(\"The reaction SMARTS is not applicable to the provided reactants.\")\n        return 0, []\n    # Check if the reaction is applicable to both combinations of reactants\n    if verbose: print('Outcome of first combo:')\n    outcome, predicted_products_flat = check_rxn(reactants=reactants, rxn=rxn, products=products, verbose=verbose)\n    if len(reactants) == 1:\n        return outcome, predicted_products_flat\n    reactants2 = [reactants[1], reactants[0]]\n    if verbose: print('Outcome of second combo:')\n    outcome2, predicted_products_flat2 = check_rxn(reactants=reactants2, rxn=rxn, products=products, verbose=verbose)\n    predicted_products_flat2\n    if outcome == 1 or outcome2 == 1:\n        outcome = 1\n        predicted_products_flat.extend(predicted_products_flat2)\n        return outcome, predicted_products_flat\n    if outcome == -1 or outcome2 == -1:\n        outcome = -1\n        predicted_products_flat.extend(predicted_products_flat2)\n        return outcome, predicted_products_flat\n    else:\n        outcome = 0\n        predicted_products_flat.extend(predicted_products_flat2)\n        return outcome, predicted_products_flat\n\ndef check_smarts(df: pd.DataFrame, rxn_smarts: str):\n    success = 0\n    failure = 0\n    total = len(df)\n    for index, row in df.iterrows():\n        reactants = row['reactants']\n        product = [row['product']]\n        print('ROW:', index)\n        outcome = check_rxn_template_works(rxn_smarts, reactants, product, verbose=True)\n        if outcome[0] != 1:\n            failure += 1\n            if outcome[0] == -1:\n                print('FAILED: THE PREDICTED PRODUCT(S) IS\/ARE WRONG')\n                for i in outcome[1]:\n                    display(Chem.MolFromSmiles(i))\n            if outcome[0] == 0:\n                print('FAILED: THE REACTION SMARTS IS NOT APPLICABLE TO THE PROVIDED REACTANTS')\n            print('REACTANT(S) BELOW:')\n            display(Chem.MolFromSmiles(reactants[0]))\n            display(Chem.MolFromSmiles(reactants[1]))\n            print('PROPER PRODUCT(S) BELOW')\n            products = [Chem.MolFromSmiles(i) for i in product]\n            for i in products:\n                display(i)\n        else:\n            success += 1\n            print('SUCCESS: THE PREDICTED PRODUCT(S) IS\/ARE RIGHT')\n            for i in outcome[1]:\n                display(Chem.MolFromSmiles(i))\n    print(f'SUCCESS: {success} \/ {total} ({(success\/len(df)*100)}%)')\n    print(f'FAILURE: {failure} \/ {total} ({failure\/len(df)*100}%)')<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">check_smarts(df, first_reductive_amination_mapping)<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"366\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=625%2C366&#038;ssl=1\" alt=\"\" class=\"wp-image-10740\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=1024%2C599&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=300%2C175&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=768%2C449&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=1536%2C898&amp;ssl=1 1536w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?resize=624%2C365&amp;ssl=1 624w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?w=1604&amp;ssl=1 1604w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.19-PM.png?w=1250&amp;ssl=1 1250w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"615\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?resize=625%2C615&#038;ssl=1\" alt=\"\" class=\"wp-image-10741\" style=\"width:655px;height:auto\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?resize=1024%2C1008&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?resize=300%2C295&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?resize=768%2C756&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?resize=624%2C614&amp;ssl=1 624w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?w=1390&amp;ssl=1 1390w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.38-PM.png?w=1250&amp;ssl=1 1250w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"682\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?resize=625%2C682&#038;ssl=1\" alt=\"\" class=\"wp-image-10742\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?resize=938%2C1024&amp;ssl=1 938w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?resize=275%2C300&amp;ssl=1 275w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?resize=768%2C839&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?resize=624%2C681&amp;ssl=1 624w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.35.50-PM.png?w=1260&amp;ssl=1 1260w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/a><\/figure>\n\n\n\n<p>Etc&#8230;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.38.18-PM.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"400\" height=\"114\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.38.18-PM.png?resize=400%2C114&#038;ssl=1\" alt=\"\" class=\"wp-image-10744\" style=\"width:192px;height:auto\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.38.18-PM.png?w=400&amp;ssl=1 400w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.38.18-PM.png?resize=300%2C86&amp;ssl=1 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/figure>\n\n\n\n<p>These results mean the reaction template only worked for one example (the one it was originally generated for) and did not work for any other examples \ud83d\ude25. While not a great result, this is most likely due to its high specificity. <\/p>\n\n\n\n<p>After some manual editing using the helpful SMARTS visualization tool <a href=\"https:\/\/smarts.plus\/\">SMARTS PLUS<\/a>, made by the University of Hamburg, we have a more general reductive amination template.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">first_reductive_amination = 'O=[CH;D2;+0:1]-[c:2].[#7;a:3]:[c:4](-[NH2;D1;+0:5]):[c:6](:[#7;a:7]):[#7;a:8]&gt;&gt;[#7;a:3]:[c:4](-[NH;D2;+0:5]-[CH2;D2;+0:1]-[c:2]):[c:6](:[#7;a:7]):[#7;a:8]'\n\ngeneral_reductive_amination_mapping = '[#6:2](=[#8])(-[#6:1]).[#7;H2,H1:3]&gt;&gt;[#6:2](-[#6:1])-[#7:3]'<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">check_smarts(df, general_reductive_amination_mapping)<\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.54.44-PM.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"418\" height=\"98\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.54.44-PM.png?resize=418%2C98&#038;ssl=1\" alt=\"\" class=\"wp-image-10750\" style=\"width:189px;height:auto\" srcset=\"https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.54.44-PM.png?w=418&amp;ssl=1 418w, https:\/\/i0.wp.com\/www.blopig.com\/blog\/wp-content\/uploads\/2024\/01\/Screenshot-2024-01-02-at-12.54.44-PM.png?resize=300%2C70&amp;ssl=1 300w\" sizes=\"auto, (max-width: 418px) 100vw, 418px\" \/><\/a><\/figure>\n\n\n\n<p>Success!!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Acknowledgements<\/h3>\n\n\n\n<p>Please check out these tools that were indespensible for this! <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>RXNutils: <a href=\"https:\/\/molecularai.github.io\/reaction_utils\/\">https:\/\/molecularai.github.io\/reaction_utils\/<\/a><\/li>\n\n\n\n<li>RXNmapper: <a href=\"https:\/\/github.com\/rxn4chemistry\/rxnmapper\">https:\/\/github.com\/rxn4chemistry\/rxnmapper<\/a><\/li>\n\n\n\n<li>SMARTS PLUS: <a href=\"http:\/\/smarts.plus\">smarts.plus<\/a><\/li>\n\n\n\n<li>And as always, RDKit: <a href=\"https:\/\/github.com\/rdkit\/rdkit\">https:\/\/github.com\/rdkit\/rdkit<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever needed to find a reaction SMARTS pattern for a certain reaction but don&#8217;t have it already written out? Do you have a reaction SMARTS pattern but need to test it on a set of reactants and products to make sure it transforms them correctly and doesn&#8217;t allow for odd reactants to work? [&hellip;]<\/p>\n","protected":false},"author":104,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","wikipediapreview_detectlinks":true,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"ngg_post_thumbnail":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[187,14,221,201],"tags":[152,129,134],"ppma_author":[717],"class_list":["post-10688","post","type-post","status-publish","format-standard","hentry","category-cheminformatics","category-howto","category-python","category-small-molecules","tag-python","tag-rdkit","tag-small-molecules"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"authors":[{"term_id":717,"user_id":104,"is_guest":0,"slug":"kate","display_name":"Kate Fieseler","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/264ae0adbd8e2e58a8d11d4b267a937306804e59ab21d1c7ce911117d9b095e5?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/10688","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/users\/104"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/comments?post=10688"}],"version-history":[{"count":5,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/10688\/revisions"}],"predecessor-version":[{"id":11210,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/posts\/10688\/revisions\/11210"}],"wp:attachment":[{"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/media?parent=10688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/categories?post=10688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/tags?post=10688"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.blopig.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=10688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}