alidenewade commited on
Commit
0b94afd
·
verified ·
1 Parent(s): f6174f8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -10
app.py CHANGED
@@ -9,6 +9,7 @@ import matplotlib.pyplot as plt
9
  import seaborn as sns
10
  import requests
11
  import io
 
12
  from PIL import Image
13
  import base64
14
 
@@ -320,6 +321,8 @@ def predict_admet_properties(smiles_dict: dict):
320
  log += f"✅ Predicted ADMET properties for {len(df)} molecules.\n"
321
  return df, log
322
 
 
 
323
  def visualize_molecule_2d_3d(smiles: str, name: str):
324
  """Generates a side-by-side 2D SVG and 3D py3Dmol HTML view for a single molecule."""
325
  log = ""
@@ -328,16 +331,21 @@ def visualize_molecule_2d_3d(smiles: str, name: str):
328
  if not mol: return f"<p>Invalid SMILES for {name}</p>", f"❌ Invalid SMILES for {name}"
329
 
330
  drawer = Draw.rdMolDraw2D.MolDraw2DSVG(400, 300)
 
331
  drawer.drawOptions().clearBackground = False
332
  drawer.drawOptions().addStereoAnnotation = True
333
  drawer.drawOptions().baseFontSize = 0.8
334
  drawer.drawOptions().circleAtoms = False
335
- drawer.drawOptions().highlightColour = (1, 0.5, 0)
336
- drawer.drawOptions().backgroundColour = (0.11, 0.11, 0.11)
337
- drawer.drawOptions().symbolColour = (1, 1, 1)
338
- drawer.drawOptions().defaultColour = (1, 1, 1)
 
 
 
 
339
  try:
340
- drawer.drawOptions().annotationColour = (1, 1, 1)
341
  except:
342
  pass
343
 
@@ -345,13 +353,51 @@ def visualize_molecule_2d_3d(smiles: str, name: str):
345
  drawer.FinishDrawing()
346
  svg_2d = drawer.GetDrawingText().replace('svg:', '')
347
 
348
- import re
 
 
349
  svg_2d = svg_2d.replace('stroke="black"', 'stroke="white"')
350
  svg_2d = svg_2d.replace('fill="black"', 'fill="white"')
351
  svg_2d = svg_2d.replace('stroke="#000000"', 'stroke="#FFFFFF"')
352
  svg_2d = svg_2d.replace('fill="#000000"', 'fill="#FFFFFF"')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  svg_2d = re.sub(r'<text(?![^>]*fill=)([^>]*?)>', r'<text fill="white"\1>', svg_2d)
354
 
 
 
 
 
 
 
 
 
 
 
355
  svg_2d = f'<div style="background-color: #1C1C1C; padding: 10px; border-radius: 5px;">{svg_2d}</div>'
356
 
357
  mol_3d = Chem.AddHs(mol)
@@ -546,18 +592,14 @@ with tab1:
546
  props_df, log_props = calculate_molecular_properties(smiles_list)
547
  full_log += log_props
548
 
549
- # --- MODIFIED LOGIC ---
550
- # assess_drug_likeness now returns two dataframes: one for analysis/plotting, one for display
551
  analysis_df, display_df, log_lipinski = assess_drug_likeness(props_df)
552
  full_log += log_lipinski
553
 
554
- # The plotting function uses the 'analysis_df' with the boolean 'Drug_Like' column
555
  props_plot, log_plot = plot_properties_dashboard(analysis_df)
556
  full_log += log_plot
557
  full_log += "\n--- Phase 1 Analysis Complete ---"
558
  st.session_state.log_p1 = full_log
559
 
560
- # The display dataframe has the pretty emojis
561
  lipinski_cols = ['Molecule', 'MW', 'LogP', 'HBD', 'HBA', 'Lipinski_Violations', 'Drug_Like']
562
  lipinski_subset_df = display_df[lipinski_cols] if not display_df.empty else pd.DataFrame(columns=lipinski_cols)
563
 
 
9
  import seaborn as sns
10
  import requests
11
  import io
12
+ import re
13
  from PIL import Image
14
  import base64
15
 
 
321
  log += f"✅ Predicted ADMET properties for {len(df)} molecules.\n"
322
  return df, log
323
 
324
+ # --- MODIFIED FUNCTION ---
325
+ # This is the updated function from the old app to correctly render 2D molecules.
326
  def visualize_molecule_2d_3d(smiles: str, name: str):
327
  """Generates a side-by-side 2D SVG and 3D py3Dmol HTML view for a single molecule."""
328
  log = ""
 
331
  if not mol: return f"<p>Invalid SMILES for {name}</p>", f"❌ Invalid SMILES for {name}"
332
 
333
  drawer = Draw.rdMolDraw2D.MolDraw2DSVG(400, 300)
334
+ # Set dark theme colors for 2D drawing
335
  drawer.drawOptions().clearBackground = False
336
  drawer.drawOptions().addStereoAnnotation = True
337
  drawer.drawOptions().baseFontSize = 0.8
338
  drawer.drawOptions().circleAtoms = False
339
+ drawer.drawOptions().highlightColour = (1, 0.5, 0) # Orange for highlights
340
+
341
+ # Set colors for dark background visibility
342
+ drawer.drawOptions().backgroundColour = (0.11, 0.11, 0.11) # Dark background
343
+ drawer.drawOptions().symbolColour = (1, 1, 1) # White symbols
344
+ drawer.drawOptions().defaultColour = (1, 1, 1) # White default color
345
+
346
+ # Try to set annotation color (this might help with (R)/(S) labels)
347
  try:
348
+ drawer.drawOptions().annotationColour = (1, 1, 1) # White annotations
349
  except:
350
  pass
351
 
 
353
  drawer.FinishDrawing()
354
  svg_2d = drawer.GetDrawingText().replace('svg:', '')
355
 
356
+ # More aggressive SVG text color fixes - target all possible black text variations
357
+
358
+ # First, comprehensive string replacements
359
  svg_2d = svg_2d.replace('stroke="black"', 'stroke="white"')
360
  svg_2d = svg_2d.replace('fill="black"', 'fill="white"')
361
  svg_2d = svg_2d.replace('stroke="#000000"', 'stroke="#FFFFFF"')
362
  svg_2d = svg_2d.replace('fill="#000000"', 'fill="#FFFFFF"')
363
+ svg_2d = svg_2d.replace('stroke="#000"', 'stroke="#FFF"')
364
+ svg_2d = svg_2d.replace('fill="#000"', 'fill="#FFF"')
365
+ svg_2d = svg_2d.replace('stroke:black', 'stroke:white')
366
+ svg_2d = svg_2d.replace('fill:black', 'fill:white')
367
+ svg_2d = svg_2d.replace('stroke:#000000', 'stroke:#FFFFFF')
368
+ svg_2d = svg_2d.replace('fill:#000000', 'fill:#FFFFFF')
369
+ svg_2d = svg_2d.replace('stroke:#000', 'stroke:#FFF')
370
+ svg_2d = svg_2d.replace('fill:#000', 'fill:#FFF')
371
+ svg_2d = svg_2d.replace('stroke="rgb(0,0,0)"', 'stroke="rgb(255,255,255)"')
372
+ svg_2d = svg_2d.replace('fill="rgb(0,0,0)"', 'fill="rgb(255,255,255)"')
373
+ svg_2d = svg_2d.replace('stroke:rgb(0,0,0)', 'stroke:rgb(255,255,255)')
374
+ svg_2d = svg_2d.replace('fill:rgb(0,0,0)', 'fill:rgb(255,255,255)')
375
+ svg_2d = svg_2d.replace('color="black"', 'color="white"')
376
+ svg_2d = svg_2d.replace('color:#000000', 'color:#FFFFFF')
377
+ svg_2d = svg_2d.replace('color:#000', 'color:#FFF')
378
+
379
+ # Aggressive regex-based fixes for all text elements
380
+ # Remove any existing fill attributes from text elements and add white fill
381
+ svg_2d = re.sub(r'<text([^>]*?)\s+fill="[^"]*"([^>]*?)>', r'<text\1\2 fill="white">', svg_2d)
382
+ svg_2d = re.sub(r'<text([^>]*?)(?<!fill="white")>', r'<text\1 fill="white">', svg_2d)
383
+
384
+ # Fix style attributes in text elements
385
+ svg_2d = re.sub(r'<text([^>]*?)style="([^"]*?)fill:\s*(?:black|#000000|#000|rgb\(0,0,0\))([^"]*?)"([^>]*?)>',
386
+ r'<text\1style="\2fill:white\3"\4>', svg_2d)
387
+
388
+ # If text elements don't have any fill specified, ensure they get white
389
  svg_2d = re.sub(r'<text(?![^>]*fill=)([^>]*?)>', r'<text fill="white"\1>', svg_2d)
390
 
391
+ # Clean up any duplicate fill attributes
392
+ svg_2d = re.sub(r'fill="white"\s+fill="white"', 'fill="white"', svg_2d)
393
+
394
+ # Final catch-all: replace any remaining black in the entire SVG
395
+ svg_2d = re.sub(r'\bblack\b', 'white', svg_2d)
396
+ svg_2d = re.sub(r'#000000', '#FFFFFF', svg_2d)
397
+ svg_2d = re.sub(r'#000\b', '#FFF', svg_2d)
398
+ svg_2d = re.sub(r'rgb\(0,\s*0,\s*0\)', 'rgb(255,255,255)', svg_2d)
399
+
400
+ # Embed the SVG within a div with a dark background for consistency
401
  svg_2d = f'<div style="background-color: #1C1C1C; padding: 10px; border-radius: 5px;">{svg_2d}</div>'
402
 
403
  mol_3d = Chem.AddHs(mol)
 
592
  props_df, log_props = calculate_molecular_properties(smiles_list)
593
  full_log += log_props
594
 
 
 
595
  analysis_df, display_df, log_lipinski = assess_drug_likeness(props_df)
596
  full_log += log_lipinski
597
 
 
598
  props_plot, log_plot = plot_properties_dashboard(analysis_df)
599
  full_log += log_plot
600
  full_log += "\n--- Phase 1 Analysis Complete ---"
601
  st.session_state.log_p1 = full_log
602
 
 
603
  lipinski_cols = ['Molecule', 'MW', 'LogP', 'HBD', 'HBA', 'Lipinski_Violations', 'Drug_Like']
604
  lipinski_subset_df = display_df[lipinski_cols] if not display_df.empty else pd.DataFrame(columns=lipinski_cols)
605