abdullahsamra commited on
Commit
a62ecf8
·
verified ·
1 Parent(s): c79eff8

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. __pycache__/app.cpython-310.pyc +0 -0
  2. app.py +115 -4
__pycache__/app.cpython-310.pyc CHANGED
Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ
 
app.py CHANGED
@@ -7,9 +7,8 @@ from datetime import datetime
7
  import gradio as gr
8
  import pandas as pd
9
  from huggingface_hub import snapshot_download
10
-
11
  from rdkit import Chem
12
- from rdkit.Chem import Descriptors, Crippen, Lipinski, rdMolDescriptors, QED
13
 
14
 
15
  BUNDLE_REPO = os.getenv("BUNDLE_REPO", "abdullahsamra/egfr-ai-bundle")
@@ -155,8 +154,8 @@ def score_smiles(smiles_text):
155
  "Outputs are computational predictions only.",
156
  ],
157
  }
158
-
159
- return df, response
160
 
161
 
162
  def get_example_table():
@@ -423,7 +422,80 @@ def generate_job_demo(num_molecules, return_top_k, docking_mode, generation_back
423
  return job_summary, df, response, str(csv_path)
424
 
425
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
 
 
427
 
428
  loaded_ok, loaded_msg = download_bundle_light()
429
 
@@ -466,6 +538,8 @@ Important:
466
  score_btn = gr.Button("Score SMILES")
467
  score_table = gr.Dataframe(label="Results table")
468
  score_json = gr.JSON(label="Backend-style JSON response")
 
 
469
 
470
  score_btn.click(
471
  score_smiles,
@@ -553,6 +627,43 @@ Generate -> Enrich -> Optional Docking
553
  outputs=[example_table, example_json],
554
  )
555
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
  with gr.Tab("Docking Contract"):
557
  gr.Markdown(
558
  """
 
7
  import gradio as gr
8
  import pandas as pd
9
  from huggingface_hub import snapshot_download
 
10
  from rdkit import Chem
11
+ from rdkit.Chem import Descriptors, Crippen, Lipinski, rdMolDescriptors, QED, AllChem
12
 
13
 
14
  BUNDLE_REPO = os.getenv("BUNDLE_REPO", "abdullahsamra/egfr-ai-bundle")
 
154
  "Outputs are computational predictions only.",
155
  ],
156
  }
157
+ csv_path = write_results_csv(df)
158
+ return df, response, csv_path
159
 
160
 
161
  def get_example_table():
 
422
  return job_summary, df, response, str(csv_path)
423
 
424
 
425
+ def write_results_csv(df: pd.DataFrame, filename: str = "score_smiles_results.csv"):
426
+ out_dir = Path("outputs")
427
+ out_dir.mkdir(parents=True, exist_ok=True)
428
+ out_path = out_dir / filename
429
+ df.to_csv(out_path, index=False)
430
+ return str(out_path)
431
+
432
+
433
+ def smiles_to_3d_file(smiles: str, file_format: str = "sdf"):
434
+ smiles = str(smiles).strip()
435
+ file_format = str(file_format).lower().strip()
436
+
437
+ if file_format not in ["sdf", "mol", "pdb"]:
438
+ return None, {
439
+ "status": "error",
440
+ "message": "Unsupported format. Choose sdf, mol, or pdb.",
441
+ }
442
+
443
+ mol = Chem.MolFromSmiles(smiles)
444
+ if mol is None:
445
+ return None, {
446
+ "status": "error",
447
+ "input_smiles": smiles,
448
+ "message": "Invalid SMILES.",
449
+ }
450
+
451
+ canonical_smiles = Chem.MolToSmiles(mol, isomericSmiles=True)
452
+
453
+ mol = Chem.AddHs(mol)
454
+
455
+ params = AllChem.ETKDGv3()
456
+ params.randomSeed = 42
457
+
458
+ embed_status = AllChem.EmbedMolecule(mol, params)
459
+ if embed_status != 0:
460
+ return None, {
461
+ "status": "error",
462
+ "input_smiles": smiles,
463
+ "canonical_smiles": canonical_smiles,
464
+ "message": "3D embedding failed.",
465
+ }
466
+
467
+ try:
468
+ AllChem.UFFOptimizeMolecule(mol, maxIters=500)
469
+ optimization_status = "UFF optimized"
470
+ except Exception as e:
471
+ optimization_status = f"UFF optimization failed, using embedded geometry only: {e}"
472
+
473
+ out_dir = Path("outputs/ligands")
474
+ out_dir.mkdir(parents=True, exist_ok=True)
475
+
476
+ safe_name = "ligand_3d"
477
+ out_path = out_dir / f"{safe_name}.{file_format}"
478
+
479
+ if file_format == "sdf":
480
+ writer = Chem.SDWriter(str(out_path))
481
+ writer.write(mol)
482
+ writer.close()
483
+ elif file_format == "mol":
484
+ Chem.MolToMolFile(mol, str(out_path))
485
+ elif file_format == "pdb":
486
+ Chem.MolToPDBFile(mol, str(out_path))
487
+
488
+ meta = {
489
+ "status": "completed",
490
+ "input_smiles": smiles,
491
+ "canonical_smiles": canonical_smiles,
492
+ "file_format": file_format,
493
+ "file_path": str(out_path),
494
+ "optimization_status": optimization_status,
495
+ "note": "This is a generated 3D conformer from SMILES, not a docked protein-ligand pose.",
496
+ }
497
 
498
+ return str(out_path), meta
499
 
500
  loaded_ok, loaded_msg = download_bundle_light()
501
 
 
538
  score_btn = gr.Button("Score SMILES")
539
  score_table = gr.Dataframe(label="Results table")
540
  score_json = gr.JSON(label="Backend-style JSON response")
541
+ score_csv = gr.File(label="Download CSV")
542
+
543
 
544
  score_btn.click(
545
  score_smiles,
 
627
  outputs=[example_table, example_json],
628
  )
629
 
630
+ with gr.Tab("SMILES to 3D File"):
631
+ gr.Markdown(
632
+ """
633
+ Convert a SMILES string into a downloadable 3D ligand file.
634
+
635
+ Supported formats:
636
+
637
+ - SDF
638
+ - MOL
639
+ - PDB
640
+
641
+ Important: this creates a 3D conformer from SMILES. It is not a docked pose inside the EGFR binding pocket.
642
+ """
643
+ )
644
+
645
+ smiles_3d_input = gr.Textbox(
646
+ label="SMILES",
647
+ value="CCO",
648
+ lines=2,
649
+ )
650
+
651
+ format_input = gr.Radio(
652
+ choices=["sdf", "mol", "pdb"],
653
+ value="sdf",
654
+ label="Output file format",
655
+ )
656
+
657
+ make_3d_btn = gr.Button("Generate 3D ligand file")
658
+ ligand_file = gr.File(label="Download 3D ligand file")
659
+ ligand_meta = gr.JSON(label="3D file metadata")
660
+
661
+ make_3d_btn.click(
662
+ smiles_to_3d_file,
663
+ inputs=[smiles_3d_input, format_input],
664
+ outputs=[ligand_file, ligand_meta],
665
+ )
666
+
667
  with gr.Tab("Docking Contract"):
668
  gr.Markdown(
669
  """