File size: 4,632 Bytes
bb649c4
81224d9
 
 
 
bb649c4
81224d9
 
 
 
 
 
 
bb649c4
81224d9
bb649c4
81224d9
 
 
df75420
bb649c4
81224d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb649c4
 
81224d9
 
 
bb649c4
 
df75420
81224d9
 
 
 
bb649c4
 
 
81224d9
 
 
 
df75420
 
 
 
81224d9
 
 
 
bb649c4
81224d9
 
 
df75420
 
bb649c4
 
81224d9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb649c4
 
1b7c1ca
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import gradio as gr
from gradio_molecule2d import molecule2d
from synformer.chem.mol import Molecule
from synformer.sampler.analog.parallel import run_sampling_one_cpu
from huggingface_hub import hf_hub_download

REPO_ID = "whgao/synformer"
CKPT_FILENAME = "sf_ed_default.ckpt"
MAT_FILENAME = "matrix.pkl"
FPI_FILENAME = "fpindex.pkl"
ckpt_path = hf_hub_download(REPO_ID, CKPT_FILENAME)
mat_path = hf_hub_download(REPO_ID, MAT_FILENAME)
fpi_path = hf_hub_download(REPO_ID, FPI_FILENAME)

last_result = {}

# Function to clear all inputs
def clear_inputs():
    # Return default or empty values to reset each input component
    return None, 4, 8, 0

def sample(smi, search_width, exhaustiveness):
    result_df = run_sampling_one_cpu(
        input=Molecule(smi),
        model_path=ckpt_path,
        mat_path=mat_path,
        fpi_path=fpi_path,
        search_width=search_width,
        exhaustiveness=exhaustiveness,
        time_limit=180,
        max_results=100,
        max_evolve_steps=24,
        sort_by_scores=True,
    )
    result_df = result_df[:30]
    last_result["results_df"] = result_df
    smiles = result_df.iloc[0]["smiles"]
    similarity = result_df.iloc[0]["score"]
    synthesis = result_df.iloc[0]["synthesis"]
    return smiles, similarity, synthesis, gr.update(maximum=len(result_df)-1)


def select_from_output(index):
    df_results = last_result["results_df"]
    return df_results.iloc[index]["smiles"], df_results.iloc[index]["score"], df_results.iloc[index]["synthesis"]

examples = [
    "COc1ccc(-c2ccnc(Nc3ccccc3)n2)cc1",
    "Nc1cccc(S(=O)(=O)N2CCCN(S(=O)(=O)c3ccc4c(c3)OCCO4)CC2)c1",
    "CN1C[C@H](Nc2cnn(C)c(=O)c2)C[C@H](c2ccccc2)C1",
    "CC[C@@H]1OC[C@@]23Cc4cc(F)c(N)cc4-c4ccc5c(c42)C(=CC(F)(F)O5)[C@@H]1C3=O",
    "O=C(OCC(=O)N1[C@H](C(=O)O)C[C@@H]2CCCC[C@@H]21)[C@H](Cc1cbccc1)NC(I)c1bcccc1",
]


with gr.Blocks() as demo:
    gr.Markdown(f"""
        # Demo of [SynFormer](https://github.com/wenhao-gao/synformer/tree/main)
        This page demonstrates the SynFormer-ED model, which takes a molecule as input—regardless of its synthetic accessibility—and outputs 
                identical or approximate molecules along with their associated synthetic paths. 
                This demo runs on CPUs and typically takes about one minute per run on local machine, but can be accelerated by reducing the 
                search width and exhaustiveness. The model may take longer if the server is busy. 
                Since the sampling is stochastic, you may run the demo multiple times to explore different results, with a maximum of 
                30 molecules displayed at once.
        To learn more about SynFormer’s architecture and applications, check out [our paper](https://github.com/wenhao-gao/synformer/tree/main).
                
        Authors: [Wenhao Gao](mailto:gaowh19@gmail.com), Shitong Luo, Connor W. Coley
        """)
    with gr.Row():
        with gr.Column(scale=0.5):
            input_molecule = molecule2d(label="SMILES Input")
            slider_1 = gr.Slider(minimum=1, maximum=16, step=1, label="Search Width", value=4)
            slider_2 = gr.Slider(minimum=1, maximum=32, step=1, label="Exhaustiveness", value=8)

            with gr.Row():
                with gr.Column(scale=0.5):
                    run_btn = gr.Button("Run on sample")
                with gr.Column(scale=0.5):
                    clear_btn = gr.Button("Clear")

        with gr.Column(scale=0.5):
            index_slider = gr.Slider(minimum=0, maximum=10, step=1, label="Select Output Index", value=0, interactive=True) 
            output_similarity = gr.Text(label="Tanimoto Similarity")
            output_molecule = molecule2d(label="Output")
            output_synpath = gr.Textbox(label="Synthetic Path")

    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### Examples")
            gr.Examples(
                examples = examples,
                inputs = [input_molecule]
            )
    
    run_btn.click(
        fn=sample, 
        inputs=[
            input_molecule, 
            slider_1, 
            slider_2
        ], 
        outputs=[
            output_molecule, 
            output_similarity,
            output_synpath,
            index_slider
        ],
        api_name="Run"
    )

    index_slider.change(
        fn=select_from_output,
        inputs=[index_slider],
        outputs=[output_molecule, output_similarity, output_synpath],
    )

    clear_btn.click(
        fn=clear_inputs,
        inputs=[],
        outputs=[input_molecule, slider_1, slider_2, index_slider]
    )

demo.launch()