|
import gradio as gr |
|
from gradio_leaderboard import Leaderboard |
|
from gradio.themes.utils import sizes |
|
import pandas as pd |
|
|
|
from evaluate import submit_data, evaluate_data |
|
from utils import make_tag_clickable, make_user_clickable, fetch_dataset_df |
|
|
|
from datetime import datetime |
|
from about import ENDPOINTS, LB_COLS, LB_DTYPES |
|
|
|
|
|
ALL_EPS = ['Average'] + ENDPOINTS |
|
|
|
def build_leaderboard(df_results): |
|
per_ep = {} |
|
for ep in ALL_EPS: |
|
df = df_results[df_results["endpoint"] == ep].copy() |
|
if df is None: |
|
print(f"[refresh] {ep} returned None; using empty DF") |
|
if df.empty: |
|
per_ep[ep] = pd.DataFrame(columns=LB_COLS) |
|
continue |
|
|
|
|
|
df['user'] = df['user'].apply(lambda x: make_user_clickable(x)).astype(str) |
|
df['model details'] = df['model_report'].apply(lambda x: make_tag_clickable(x)).astype(str) |
|
|
|
per_ep[ep] = df[LB_COLS] |
|
|
|
return per_ep |
|
|
|
|
|
current_df = fetch_dataset_df() |
|
|
|
def gradio_interface(): |
|
|
|
with gr.Blocks(title="OpenADMET ADMET Challenge", theme=gr.themes.Default(text_size=sizes.text_lg)) as demo: |
|
timer = gr.Timer(15) |
|
data_version = gr.State(0) |
|
def update_current_dataframe(v): |
|
global current_df |
|
new_df = fetch_dataset_df() |
|
if not current_df.equals(new_df): |
|
current_df = new_df |
|
return v + 1 |
|
return v |
|
timer.tick(fn=update_current_dataframe, inputs=[data_version], outputs=data_version) |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(scale=8): |
|
gr.Markdown(""" |
|
## Welcome to the OpenADMET + XXX Blind Challenge! |
|
Your task is to develop and submit predictive models for key ADMET properties on a blinded test set of real world drug discovery data π§βπ¬ |
|
|
|
Go to the **Leaderboard** to check out how the challenge is going. |
|
To participate, head out to the **Submit** tab and upload your results as a `CSV` file. |
|
""" |
|
) |
|
with gr.Column(scale=1): |
|
gr.Image( |
|
value="./_static/challenge_logo.png", |
|
show_label=False, |
|
show_download_button=False, |
|
width="10vw", |
|
) |
|
|
|
|
|
welcome_md = """ |
|
# π OpenADMET + XXX |
|
## Computational Blind Challenge in ADMET |
|
|
|
This challenge is a community-driven initiative to benchmark predictive models for ADMET properties in drug discovery, |
|
hosted by **OpenADMET** in collaboration with **XXX**. |
|
|
|
|
|
## Why are ADMET properties important in drug discovery? |
|
Small molecules continue to be the bricks and mortar of drug discovery globally, accounting for ~75% of FDA approvals over the last decade. |
|
Oral bioavailability, easily tunable properties, modulation of a wide range of mechanisms, |
|
and ease of manufacturing make small molecules highly attractive as therapeutic agents, a trend that is not expected to drastically change, |
|
despite increased interest in biologics. Indeed, newer small molecule modalities such as degraders, molecular glues, and antibody-drug conjugates |
|
(to name a few) make understanding small molecule properties more important than ever. |
|
|
|
It is fairly difficult to predict the lifetime and distribution of small molecules within the body. Additionally, |
|
interaction with off-targets can cause safety issues and toxicity. Collectively these *Absorption*, *Distribution*, *Metabolism*, *Excretion*, *Toxicology*--or **ADMET**--properties |
|
sit in the middle of the assay cascade and can make or break preclinical candidate molecules. |
|
|
|
**OpenADMET** aims to address these challenges through an open science effort to build predictive models of ADMET properties by characterizing the proteins and mechanisms |
|
that give rise to these properties through integrated structural biology, high throughput experimentation and integrative computational models. |
|
Read more about our strategy to transform drug discovery on our [website](https://openadmet.org/community/blogs/whatisopenadmet/). |
|
|
|
For this blind challenge we selected ten (10) crucial endpoints for the community to predict: |
|
- LogD |
|
- Kinetic Solubility **KSOL**: uM |
|
- Mouse Liver Microsomal (**MLM**) *CLint*: mL/min/kg |
|
- Human Liver Microsomal (**HLM**) *Clint*: mL/min/kg |
|
- Caco-2 Efflux Ratio |
|
- Caco-2 Papp A>B (10^-6 cm/s) |
|
- Mouse Plasma Protein Binding (**MPPB**): % Unbound |
|
- Mouse Brain Protein Binding (**MBPB**): % Unbound |
|
- Rat Liver Microsomal (**RLM**) *Clint*: mL/min/kg |
|
- Mouse Gastrocnemius Muscle Binding (**MGMB**): % Unbound |
|
|
|
## β
How to Participate |
|
1. **Register**: Create an account with Hugging Face. |
|
2. **Download the Public Dataset**: Clone the XXX dataset [link] |
|
3. **Train Your Model**: Use the provided training data for each ADMET property of your choice. |
|
4. **Submit Predictions**: Follow the instructions in the *Submit* tab to upload your predictions. |
|
5. Join the discussion on the [Challenge Discord](link)! |
|
|
|
## π Data: |
|
|
|
The training set will have the following variables: |
|
|
|
| Column | Unit | data type | Description | |
|
|:-----------------------------|-----------|-----------|:-------------| |
|
| Molecule Name | | str | Identifier for the molecule | |
|
| Smiles | | str | Text representation of the 2D molecular structure | |
|
| LogD | | float | LogD calculation | |
|
| KSol | uM | float | Kinetic Solubility | |
|
| MLM CLint | mL/min/kg | float | Mouse Liver Microsomal | |
|
| HLM CLint | mL/min/kg | float | Human Liver Microsomal | |
|
| Caco-2 Permeability Efflux | | float | Caco-2 Permeability Efflux | |
|
| Caco-2 Permeability Papp A>B | 10^-6 cm/s| float | Caco-2 Permeability Papp A>B | |
|
| MPPB | % Unbound | float | Mouse Plasma Protein Binding | |
|
| MBPB | % Unbound | float | Mouse Brain Protein Binding | |
|
| RLM CLint | mL/min/kg | float | Rat Liver Microsomal Stability | |
|
| MGMB. | % Unbound | float | Mouse Gastrocnemius Muscle Binding | |
|
|
|
At test time, we will only provide the Molecule Name and Smiles. Make sure your submission file has the same columns! |
|
|
|
## π Evaluation |
|
The challenge will be judged based on the judging criteria outlined here. |
|
|
|
- TBD |
|
|
|
π
**Timeline**: |
|
- TBD |
|
|
|
--- |
|
|
|
""" |
|
|
|
|
|
gr.HTML(""" |
|
<style> |
|
/* bold only the "Overall" tab label */ |
|
#lb_subtabs [role="tab"][aria-controls="all_tab"] { |
|
font-weight: 700 !important; |
|
} |
|
</style> |
|
""") |
|
with gr.Tabs(elem_classes="tab-buttons"): |
|
lboard_dict = {} |
|
|
|
with gr.TabItem("π About"): |
|
gr.Markdown(welcome_md) |
|
|
|
with gr.TabItem("π Leaderboard", elem_id="lb_subtabs"): |
|
gr.Markdown("View the leaderboard for each ADMET endpoint by selecting the appropiate tab.") |
|
|
|
|
|
|
|
with gr.TabItem('OVERALL', elem_id="all_tab"): |
|
lboard_dict['Average'] = Leaderboard( |
|
value=build_leaderboard(current_df)['Average'], |
|
datatype=LB_DTYPES, |
|
select_columns=LB_COLS, |
|
search_columns=["user"], |
|
render=True, |
|
every=15, |
|
) |
|
|
|
for endpoint in ENDPOINTS: |
|
with gr.TabItem(endpoint): |
|
lboard_dict[endpoint] = Leaderboard( |
|
value=build_leaderboard(current_df)[endpoint], |
|
datatype=LB_DTYPES, |
|
select_columns=LB_COLS, |
|
search_columns=["user"], |
|
render=True, |
|
every=15, |
|
) |
|
|
|
def refresh_if_changed(): |
|
per_ep = build_leaderboard(current_df) |
|
|
|
return [per_ep[ep] for ep in ALL_EPS] |
|
|
|
data_version.change(fn=refresh_if_changed, outputs=[lboard_dict[ep] for ep in ALL_EPS]) |
|
|
|
with gr.TabItem("βοΈ Submit"): |
|
gr.Markdown( |
|
""" |
|
# ADMET Endpoints Submission |
|
Upload your prediction files here as a csv file. |
|
""" |
|
) |
|
filename = gr.State(value=None) |
|
eval_state = gr.State(value=None) |
|
user_state = gr.State(value=None) |
|
|
|
with gr.Row(): |
|
|
|
with gr.Column(): |
|
gr.Markdown( |
|
""" |
|
## Participant Information |
|
To participate, we **only** require a Hugging Face username, which will be displayed on the leaderboard. |
|
Other information is optional but helps us track participation. |
|
If you wish to be included in Challenge discussions, please provide your Discord username and email. |
|
If you wish to be included in a future publication with the Challenge results, please provide your name and affiliation. |
|
|
|
We also ask you to provide a link to a report decribing your method. While not mandatory at the time of participation, |
|
you need to submit the link before the challenge deadline in order to be considered for the final leaderboard. |
|
|
|
""" |
|
) |
|
|
|
username_input = gr.Textbox( |
|
label="Username", |
|
placeholder="Enter your Hugging Face username", |
|
info="This will be displayed on the leaderboard." |
|
) |
|
with gr.Column(): |
|
|
|
participant_name = gr.Textbox( |
|
label="Participant Name", |
|
placeholder="Enter your name (optional)", |
|
info="This will not be displayed on the leaderboard but will be used for tracking participation." |
|
) |
|
discord_username= gr.Textbox( |
|
label="Discord Username", |
|
placeholder="Enter your Discord username (optional)", |
|
info="Enter the username you will use for the Discord channel (if you are planning to engage in the discussion)." |
|
) |
|
email = gr.Textbox( |
|
label="Email", |
|
placeholder="Enter your email (optional)", |
|
) |
|
affiliation = gr.Textbox( |
|
label="Affiliation", |
|
placeholder="Enter your school/company affiliation (optional)", |
|
) |
|
model_tag = gr.Textbox( |
|
label="Model Report", |
|
placeholder="Link to a report describing your method (optional)", |
|
) |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown( |
|
""" |
|
## Submission Instructions |
|
Upload a single CSV file containing your predictions for all ligands in the test set. |
|
Only your latest submission will be considered. |
|
|
|
You can download the ligand test set here (lik/to/download/smiles/csv). |
|
""" |
|
) |
|
with gr.Column(): |
|
predictions_file = gr.File(label="Single file with ADMET predictions (.csv)", |
|
file_types=[".csv"], |
|
file_count="single",) |
|
|
|
username_input.change( |
|
fn=lambda x: x if x.strip() else None, |
|
inputs=username_input, |
|
outputs=user_state |
|
) |
|
|
|
submit_btn = gr.Button("Submit Predictions") |
|
message = gr.Textbox(label="Status", lines=1, visible=False) |
|
|
|
submit_btn.click( |
|
submit_data, |
|
inputs=[predictions_file, user_state, participant_name, discord_username, email, affiliation, model_tag], |
|
outputs=[message, filename], |
|
).success( |
|
fn=lambda m: gr.update(value=m, visible=True), |
|
inputs=[message], |
|
outputs=[message], |
|
).success( |
|
fn=evaluate_data, |
|
inputs=[filename], |
|
outputs=[eval_state] |
|
) |
|
return demo |
|
|
|
if __name__ == "__main__": |
|
gradio_interface().launch() |