Vaishnav14220 commited on
Commit
31d1503
·
1 Parent(s): a6b2934

Add interactive 3D molecule viewer with 3Dmol.js in the app

Browse files
Files changed (1) hide show
  1. app.py +40 -16
app.py CHANGED
@@ -84,29 +84,53 @@ def name_to_3d_molecule(name: str) -> tuple:
84
  # Convert image to base64
85
  import io
86
  import base64
 
87
  buffered = io.BytesIO()
88
  img.save(buffered, format="PNG")
89
  img_str = base64.b64encode(buffered.getvalue()).decode()
90
 
91
  # Get SMILES string
92
  canonical_smiles = Chem.MolToSmiles(mol_2d)
 
 
 
93
 
94
- # Create HTML with 2D image and SDF content
95
  html_content = f"""
96
- <div style="text-align: center; padding: 20px;">
97
- <h3>{name}</h3>
98
- <p><strong>SMILES:</strong> {canonical_smiles}</p>
99
- <img src="data:image/png;base64,{img_str}" style="max-width: 100%; border: 1px solid #ddd; border-radius: 8px; padding: 10px; background: white;">
100
- <p style="margin-top: 10px; color: #666;">2D Structure Preview</p>
101
- <div style="margin-top: 20px; padding: 15px; background-color: #d4edda; border: 2px solid #28a745; border-radius: 8px;">
102
- <p style="color: #155724; font-size: 16px; font-weight: bold; margin: 0;">
103
- 3D SDF Content Ready!
104
- </p>
105
- <p style="color: #155724; margin: 5px 0 0 0;">
106
- Copy the SDF content below and save as .sdf file
107
- </p>
 
 
 
108
  </div>
109
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  """
111
 
112
  return html_content, sdf_content
@@ -160,11 +184,11 @@ molecule_3d_interface = gr.Interface(
160
  fn=name_to_3d_molecule,
161
  inputs=gr.Textbox(label="Chemical Name", placeholder="e.g., benzene, aspirin, caffeine, glucose"),
162
  outputs=[
163
- gr.HTML(label="2D Preview"),
164
- gr.Textbox(label="3D SDF Content (copy and save as .sdf file)", lines=20, max_lines=30)
165
  ],
166
  api_name="name_to_molecule",
167
- description="Get 2D structure preview and 3D SDF content. Copy the SDF text and save as .sdf file to open in PyMOL, Avogadro, ChimeraX, or other molecular viewers.",
168
  cache_examples=False,
169
  )
170
 
 
84
  # Convert image to base64
85
  import io
86
  import base64
87
+ import json
88
  buffered = io.BytesIO()
89
  img.save(buffered, format="PNG")
90
  img_str = base64.b64encode(buffered.getvalue()).decode()
91
 
92
  # Get SMILES string
93
  canonical_smiles = Chem.MolToSmiles(mol_2d)
94
+
95
+ # Escape SDF content for JavaScript
96
+ sdf_escaped = json.dumps(sdf_content)
97
 
98
+ # Create HTML with 3D viewer
99
  html_content = f"""
100
+ <div style="padding: 20px;">
101
+ <h3 style="text-align: center;">{name}</h3>
102
+ <p style="text-align: center;"><strong>SMILES:</strong> {canonical_smiles}</p>
103
+
104
+ <div style="display: flex; gap: 20px; justify-content: center; flex-wrap: wrap;">
105
+ <div style="text-align: center;">
106
+ <h4>2D Structure</h4>
107
+ <img src="data:image/png;base64,{img_str}" style="max-width: 400px; border: 1px solid #ddd; border-radius: 8px; padding: 10px; background: white;">
108
+ </div>
109
+
110
+ <div style="text-align: center;">
111
+ <h4>3D Interactive Model</h4>
112
+ <div id="viewer3d" style="width: 400px; height: 400px; border: 1px solid #ddd; border-radius: 8px; background: white; position: relative;"></div>
113
+ <p style="margin-top: 10px; font-size: 12px; color: #666;">Drag to rotate, scroll to zoom</p>
114
+ </div>
115
  </div>
116
  </div>
117
+
118
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
119
+ <script src="https://3dmol.csb.pitt.edu/build/3Dmol-min.js"></script>
120
+ <script>
121
+ $(document).ready(function() {{
122
+ let element = document.getElementById('viewer3d');
123
+ let config = {{ backgroundColor: 'white' }};
124
+ let viewer = $3Dmol.createViewer(element, config);
125
+
126
+ let sdfData = {sdf_escaped};
127
+ viewer.addModel(sdfData, "sdf");
128
+ viewer.setStyle({{}}, {{stick: {{radius: 0.15, colorscheme: 'Jmol'}}, sphere: {{radius: 0.4, colorscheme: 'Jmol'}}}});
129
+ viewer.zoomTo();
130
+ viewer.render();
131
+ viewer.zoom(1.2, 1000);
132
+ }});
133
+ </script>
134
  """
135
 
136
  return html_content, sdf_content
 
184
  fn=name_to_3d_molecule,
185
  inputs=gr.Textbox(label="Chemical Name", placeholder="e.g., benzene, aspirin, caffeine, glucose"),
186
  outputs=[
187
+ gr.HTML(label="2D and 3D Molecular Viewer"),
188
+ gr.Textbox(label="3D SDF Content (optional - for external viewers)", lines=10, max_lines=20, visible=False)
189
  ],
190
  api_name="name_to_molecule",
191
+ description="View 2D structure and interactive 3D molecule. Drag to rotate the 3D model, scroll to zoom.",
192
  cache_examples=False,
193
  )
194