Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -142,7 +142,7 @@ def batch_predict(app_choice, file_obj):
|
|
| 142 |
def generate_and_screen(num_to_gen, app_mode, toggle_view, motifs=[], limit_aro=False, max_mw=500, seed=None):
|
| 143 |
candidates = []
|
| 144 |
generated_fps = []
|
| 145 |
-
max_attempts =
|
| 146 |
attempts = 0
|
| 147 |
|
| 148 |
parent_fp = None
|
|
@@ -157,6 +157,8 @@ def generate_and_screen(num_to_gen, app_mode, toggle_view, motifs=[], limit_aro=
|
|
| 157 |
|
| 158 |
while len(candidates) < num_to_gen and attempts < max_attempts:
|
| 159 |
attempts += 1
|
|
|
|
|
|
|
| 160 |
input_seq = torch.tensor([[char_to_int['<SOS>']]])
|
| 161 |
h, generated = None, ""
|
| 162 |
for _ in range(100):
|
|
@@ -441,25 +443,32 @@ def mutate_smiles(smiles):
|
|
| 441 |
|
| 442 |
def check_constraints(mol, motifs, limit_aromatic, max_mw):
|
| 443 |
if not mol: return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
if Descriptors.MolWt(mol) > max_mw: return False
|
| 445 |
|
| 446 |
# 🧪 ADVANCED CHEMICAL LOGIC MAP
|
| 447 |
pattern_map = {
|
| 448 |
# --- ENFORCE BIODEGRADABLE MOTIFS ---
|
| 449 |
"Esters (Biodegradable)": "[CX3](=[OX1])O[#6]",
|
| 450 |
-
"Carbonates (Biodegradable)": "
|
| 451 |
-
"PLA-type (Lactide/Lactic)": "
|
| 452 |
"Anhydrides (Fast Degrading)": "C(=O)OC(=O)",
|
| 453 |
|
| 454 |
-
# --- LOCK FUNCTIONAL GROUPS ---
|
| 455 |
"Amides (High Strength)": "[NX3][CX3](=[OX1])[#6]",
|
| 456 |
"Sulfones (Thermal Stability)": "S(=O)(=O)",
|
| 457 |
"Urethanes": "[NX3]C(=O)O",
|
| 458 |
|
| 459 |
-
|
| 460 |
-
"
|
| 461 |
-
"
|
| 462 |
-
"Cyclic-Aliphatic": "[C#6]1[C#6][C#6][C#6][C#6][C#6]1" # Cyclohexane type
|
| 463 |
}
|
| 464 |
|
| 465 |
for m in motifs:
|
|
@@ -472,7 +481,7 @@ def check_constraints(mol, motifs, limit_aromatic, max_mw):
|
|
| 472 |
aromatic_atoms = len(mol.GetAromaticAtoms())
|
| 473 |
total_atoms = mol.GetNumAtoms()
|
| 474 |
# Requirement: Max 20% of atoms can be aromatic
|
| 475 |
-
if total_atoms > 0 and (aromatic_atoms / total_atoms) > 0.
|
| 476 |
return False
|
| 477 |
|
| 478 |
return True
|
|
@@ -511,12 +520,14 @@ with gr.Blocks(title="PolymerDesignAI") as demo:
|
|
| 511 |
gr.Markdown("🔒 **Constraint-Based Generation (Hard Filters)**")
|
| 512 |
must_have = gr.Dropdown(
|
| 513 |
[
|
|
|
|
| 514 |
"Esters (Biodegradable)", "Carbonates (Biodegradable)",
|
| 515 |
"PLA-type (Lactide/Lactic)", "Anhydrides (Fast Degrading)",
|
| 516 |
"Amides (High Strength)", "Sulfones (Thermal Stability)",
|
| 517 |
"Urethanes", "Aryl-Monomer", "Aliphatic-Chain"
|
| 518 |
],
|
| 519 |
-
|
|
|
|
| 520 |
label="Lock Functional Groups & Motifs",
|
| 521 |
interactive=True # Ensures the dropdown is clickable
|
| 522 |
)
|
|
@@ -602,7 +613,8 @@ with gr.Blocks(title="PolymerDesignAI") as demo:
|
|
| 602 |
|
| 603 |
csv_out = gr.File(label="Download Full Results")
|
| 604 |
|
| 605 |
-
def on_gen_complete(num, mode, view, motifs, limit_aro, mw):
|
|
|
|
| 606 |
df, path, fig = generate_and_screen(num, mode, view, motifs, limit_aro, mw)
|
| 607 |
|
| 608 |
def get_dropdown_icon(status_text):
|
|
|
|
| 142 |
def generate_and_screen(num_to_gen, app_mode, toggle_view, motifs=[], limit_aro=False, max_mw=500, seed=None):
|
| 143 |
candidates = []
|
| 144 |
generated_fps = []
|
| 145 |
+
max_attempts = 1500
|
| 146 |
attempts = 0
|
| 147 |
|
| 148 |
parent_fp = None
|
|
|
|
| 157 |
|
| 158 |
while len(candidates) < num_to_gen and attempts < max_attempts:
|
| 159 |
attempts += 1
|
| 160 |
+
if attempts % 100 == 0:
|
| 161 |
+
gr.Info(f"Searched {attempts} molecules... Found {len(candidates)} matches.")
|
| 162 |
input_seq = torch.tensor([[char_to_int['<SOS>']]])
|
| 163 |
h, generated = None, ""
|
| 164 |
for _ in range(100):
|
|
|
|
| 443 |
|
| 444 |
def check_constraints(mol, motifs, limit_aromatic, max_mw):
|
| 445 |
if not mol: return False
|
| 446 |
+
|
| 447 |
+
if not motifs or motifs == "None":
|
| 448 |
+
active_motifs = []
|
| 449 |
+
|
| 450 |
+
elif isinstance(motifs, str):
|
| 451 |
+
active_motifs = [motifs]
|
| 452 |
+
else:
|
| 453 |
+
active_motifs = motifs
|
| 454 |
+
|
| 455 |
if Descriptors.MolWt(mol) > max_mw: return False
|
| 456 |
|
| 457 |
# 🧪 ADVANCED CHEMICAL LOGIC MAP
|
| 458 |
pattern_map = {
|
| 459 |
# --- ENFORCE BIODEGRADABLE MOTIFS ---
|
| 460 |
"Esters (Biodegradable)": "[CX3](=[OX1])O[#6]",
|
| 461 |
+
"Carbonates (Biodegradable)": "[OX2]C(=O)[OX2]", # Faster
|
| 462 |
+
"PLA-type (Lactide/Lactic)": "C(C)C(=O)O",
|
| 463 |
"Anhydrides (Fast Degrading)": "C(=O)OC(=O)",
|
| 464 |
|
|
|
|
| 465 |
"Amides (High Strength)": "[NX3][CX3](=[OX1])[#6]",
|
| 466 |
"Sulfones (Thermal Stability)": "S(=O)(=O)",
|
| 467 |
"Urethanes": "[NX3]C(=O)O",
|
| 468 |
|
| 469 |
+
"Aryl-Monomer": "a",
|
| 470 |
+
"Aliphatic-Chain": "CCCC",
|
| 471 |
+
"Cyclic-Aliphatic": "C1CCCCC1"
|
|
|
|
| 472 |
}
|
| 473 |
|
| 474 |
for m in motifs:
|
|
|
|
| 481 |
aromatic_atoms = len(mol.GetAromaticAtoms())
|
| 482 |
total_atoms = mol.GetNumAtoms()
|
| 483 |
# Requirement: Max 20% of atoms can be aromatic
|
| 484 |
+
if total_atoms > 0 and (aromatic_atoms / total_atoms) > 0.35:
|
| 485 |
return False
|
| 486 |
|
| 487 |
return True
|
|
|
|
| 520 |
gr.Markdown("🔒 **Constraint-Based Generation (Hard Filters)**")
|
| 521 |
must_have = gr.Dropdown(
|
| 522 |
[
|
| 523 |
+
"None",
|
| 524 |
"Esters (Biodegradable)", "Carbonates (Biodegradable)",
|
| 525 |
"PLA-type (Lactide/Lactic)", "Anhydrides (Fast Degrading)",
|
| 526 |
"Amides (High Strength)", "Sulfones (Thermal Stability)",
|
| 527 |
"Urethanes", "Aryl-Monomer", "Aliphatic-Chain"
|
| 528 |
],
|
| 529 |
+
value="None",
|
| 530 |
+
multiselect=False,
|
| 531 |
label="Lock Functional Groups & Motifs",
|
| 532 |
interactive=True # Ensures the dropdown is clickable
|
| 533 |
)
|
|
|
|
| 613 |
|
| 614 |
csv_out = gr.File(label="Download Full Results")
|
| 615 |
|
| 616 |
+
def on_gen_complete(num, mode, view, motifs, limit_aro, mw, progress=gr.Progress()):
|
| 617 |
+
progress(0, desc="🔍 Initializing Generative AI...")
|
| 618 |
df, path, fig = generate_and_screen(num, mode, view, motifs, limit_aro, mw)
|
| 619 |
|
| 620 |
def get_dropdown_icon(status_text):
|