Spaces:
Runtime error
Runtime error
Vaishnav14220
commited on
Commit
·
7357bca
1
Parent(s):
e2cbfc6
Add proper orbital shapes: s (sphere), p (dumbbell), d (cloverleaf) with better checkbox visibility
Browse files
app.py
CHANGED
|
@@ -167,35 +167,141 @@ def name_to_3d_molecule(name: str, show_orbitals: bool = False) -> tuple:
|
|
| 167 |
|
| 168 |
if show_orbitals:
|
| 169 |
import numpy as np
|
| 170 |
-
|
|
|
|
| 171 |
orbital_radius = {
|
| 172 |
'H': 0.6, 'C': 0.9, 'N': 0.8, 'O': 0.75,
|
| 173 |
'F': 0.7, 'Cl': 1.0, 'Br': 1.15, 'I': 1.4,
|
| 174 |
'P': 1.1, 'S': 1.05, 'B': 0.95, 'Si': 1.2
|
| 175 |
}
|
| 176 |
|
| 177 |
-
#
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
#
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
|
|
|
|
|
|
|
| 188 |
color = color_map.get(elem, '#FF1493')
|
| 189 |
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
|
| 200 |
# Create figure
|
| 201 |
fig = go.Figure(data=data_traces)
|
|
@@ -273,7 +379,7 @@ molecule_3d_interface = gr.Interface(
|
|
| 273 |
fn=name_to_3d_molecule,
|
| 274 |
inputs=[
|
| 275 |
gr.Textbox(label="Chemical Name", placeholder="e.g., benzene, aspirin, caffeine, glucose"),
|
| 276 |
-
gr.Checkbox(label="Show Electron Orbitals", value=False)
|
| 277 |
],
|
| 278 |
outputs=[
|
| 279 |
gr.HTML(label="2D Structure"),
|
|
@@ -281,9 +387,16 @@ molecule_3d_interface = gr.Interface(
|
|
| 281 |
gr.Textbox(label="3D SDF Content (Optional - for external viewers)", lines=10, max_lines=20, visible=False)
|
| 282 |
],
|
| 283 |
api_name="name_to_molecule",
|
| 284 |
-
description="View 2D structure and interactive 3D molecule with atom labels. Click and drag to rotate, scroll to zoom!
|
| 285 |
cache_examples=False,
|
| 286 |
-
examples=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
)
|
| 288 |
|
| 289 |
|
|
|
|
| 167 |
|
| 168 |
if show_orbitals:
|
| 169 |
import numpy as np
|
| 170 |
+
|
| 171 |
+
# Orbital size reference
|
| 172 |
orbital_radius = {
|
| 173 |
'H': 0.6, 'C': 0.9, 'N': 0.8, 'O': 0.75,
|
| 174 |
'F': 0.7, 'Cl': 1.0, 'Br': 1.15, 'I': 1.4,
|
| 175 |
'P': 1.1, 'S': 1.05, 'B': 0.95, 'Si': 1.2
|
| 176 |
}
|
| 177 |
|
| 178 |
+
# Get electron configuration for each atom to determine orbital types
|
| 179 |
+
def get_orbitals(atomic_num):
|
| 180 |
+
"""Return list of orbitals for an atom based on electron configuration"""
|
| 181 |
+
# Simplified orbital visualization - show valence orbitals
|
| 182 |
+
if atomic_num == 1: # H: 1s
|
| 183 |
+
return ['s']
|
| 184 |
+
elif atomic_num <= 2: # He: 1s
|
| 185 |
+
return ['s']
|
| 186 |
+
elif atomic_num <= 10: # Li-Ne: has s and p
|
| 187 |
+
return ['s', 'p']
|
| 188 |
+
elif atomic_num <= 18: # Na-Ar: has s and p
|
| 189 |
+
return ['s', 'p']
|
| 190 |
+
elif atomic_num <= 36: # K-Kr: has s, p, d
|
| 191 |
+
return ['s', 'p', 'd']
|
| 192 |
+
else: # Rb onwards: has s, p, d, f
|
| 193 |
+
return ['s', 'p', 'd', 'f']
|
| 194 |
+
|
| 195 |
+
# Create orbital shapes around each atom
|
| 196 |
+
for idx, (x, y, z, elem) in enumerate(zip(x_coords, y_coords, z_coords, elements)):
|
| 197 |
+
atom = atoms[idx]
|
| 198 |
+
atomic_num = atom.GetAtomicNum()
|
| 199 |
+
orbitals = get_orbitals(atomic_num)
|
| 200 |
|
| 201 |
+
# Base radius for orbitals
|
| 202 |
+
base_radius = orbital_radius.get(elem, 0.8)
|
| 203 |
color = color_map.get(elem, '#FF1493')
|
| 204 |
|
| 205 |
+
# S orbital (spherical)
|
| 206 |
+
if 's' in orbitals:
|
| 207 |
+
u = np.linspace(0, 2 * np.pi, 25)
|
| 208 |
+
v = np.linspace(0, np.pi, 20)
|
| 209 |
+
s_radius = base_radius * 0.6
|
| 210 |
+
sphere_x = x + s_radius * np.outer(np.cos(u), np.sin(v))
|
| 211 |
+
sphere_y = y + s_radius * np.outer(np.sin(u), np.sin(v))
|
| 212 |
+
sphere_z = z + s_radius * np.outer(np.ones(np.size(u)), np.cos(v))
|
| 213 |
+
|
| 214 |
+
s_orbital = go.Surface(
|
| 215 |
+
x=sphere_x, y=sphere_y, z=sphere_z,
|
| 216 |
+
colorscale=[[0, color], [1, color]],
|
| 217 |
+
showscale=False,
|
| 218 |
+
opacity=0.2,
|
| 219 |
+
name=f'{elem}-s',
|
| 220 |
+
hoverinfo='skip'
|
| 221 |
+
)
|
| 222 |
+
data_traces.append(s_orbital)
|
| 223 |
+
|
| 224 |
+
# P orbitals (dumbbell shaped - 3 orientations: px, py, pz)
|
| 225 |
+
if 'p' in orbitals:
|
| 226 |
+
p_radius = base_radius * 1.0
|
| 227 |
+
p_length = base_radius * 1.5
|
| 228 |
+
|
| 229 |
+
# Create dumbbell shape for p orbitals
|
| 230 |
+
u = np.linspace(0, 2 * np.pi, 20)
|
| 231 |
+
v = np.linspace(-1, 1, 15)
|
| 232 |
+
|
| 233 |
+
# Pz orbital (along z-axis)
|
| 234 |
+
pz_r = p_radius * np.sqrt(1 - v**2)
|
| 235 |
+
pz_z_vals = z + p_length * v
|
| 236 |
+
pz_x = x + np.outer(pz_r, np.cos(u))
|
| 237 |
+
pz_y = y + np.outer(pz_r, np.sin(u))
|
| 238 |
+
pz_z = np.outer(pz_z_vals, np.ones(len(u)))
|
| 239 |
+
|
| 240 |
+
pz_orbital = go.Surface(
|
| 241 |
+
x=pz_x, y=pz_y, z=pz_z,
|
| 242 |
+
colorscale=[[0, color], [0.5, color], [1, color]],
|
| 243 |
+
showscale=False,
|
| 244 |
+
opacity=0.15,
|
| 245 |
+
name=f'{elem}-pz',
|
| 246 |
+
hoverinfo='skip'
|
| 247 |
+
)
|
| 248 |
+
data_traces.append(pz_orbital)
|
| 249 |
+
|
| 250 |
+
# Px orbital (along x-axis)
|
| 251 |
+
px_r = p_radius * np.sqrt(1 - v**2)
|
| 252 |
+
px_x_vals = x + p_length * v
|
| 253 |
+
px_x = np.outer(px_x_vals, np.ones(len(u)))
|
| 254 |
+
px_y = y + np.outer(px_r, np.cos(u))
|
| 255 |
+
px_z = z + np.outer(px_r, np.sin(u))
|
| 256 |
+
|
| 257 |
+
px_orbital = go.Surface(
|
| 258 |
+
x=px_x, y=px_y, z=px_z,
|
| 259 |
+
colorscale=[[0, color], [0.5, color], [1, color]],
|
| 260 |
+
showscale=False,
|
| 261 |
+
opacity=0.15,
|
| 262 |
+
name=f'{elem}-px',
|
| 263 |
+
hoverinfo='skip'
|
| 264 |
+
)
|
| 265 |
+
data_traces.append(px_orbital)
|
| 266 |
+
|
| 267 |
+
# Py orbital (along y-axis)
|
| 268 |
+
py_r = p_radius * np.sqrt(1 - v**2)
|
| 269 |
+
py_y_vals = y + p_length * v
|
| 270 |
+
py_x = x + np.outer(py_r, np.cos(u))
|
| 271 |
+
py_y = np.outer(py_y_vals, np.ones(len(u)))
|
| 272 |
+
py_z = z + np.outer(py_r, np.sin(u))
|
| 273 |
+
|
| 274 |
+
py_orbital = go.Surface(
|
| 275 |
+
x=py_x, y=py_y, z=py_z,
|
| 276 |
+
colorscale=[[0, color], [0.5, color], [1, color]],
|
| 277 |
+
showscale=False,
|
| 278 |
+
opacity=0.15,
|
| 279 |
+
name=f'{elem}-py',
|
| 280 |
+
hoverinfo='skip'
|
| 281 |
+
)
|
| 282 |
+
data_traces.append(py_orbital)
|
| 283 |
+
|
| 284 |
+
# D orbitals (for transition metals) - simplified cloverleaf shape
|
| 285 |
+
if 'd' in orbitals and elem not in ['H', 'C', 'N', 'O', 'F', 'S', 'P', 'Cl']:
|
| 286 |
+
d_radius = base_radius * 1.2
|
| 287 |
+
theta = np.linspace(0, 2 * np.pi, 25)
|
| 288 |
+
phi = np.linspace(0, np.pi, 15)
|
| 289 |
+
|
| 290 |
+
# Simplified d-orbital (four-lobed)
|
| 291 |
+
r = d_radius * np.abs(np.outer(np.sin(2 * phi), np.cos(2 * theta)))
|
| 292 |
+
d_x = x + r * np.outer(np.sin(phi), np.cos(theta))
|
| 293 |
+
d_y = y + r * np.outer(np.sin(phi), np.sin(theta))
|
| 294 |
+
d_z = z + r * np.outer(np.cos(phi), np.ones(len(theta)))
|
| 295 |
+
|
| 296 |
+
d_orbital = go.Surface(
|
| 297 |
+
x=d_x, y=d_y, z=d_z,
|
| 298 |
+
colorscale=[[0, color], [1, color]],
|
| 299 |
+
showscale=False,
|
| 300 |
+
opacity=0.12,
|
| 301 |
+
name=f'{elem}-d',
|
| 302 |
+
hoverinfo='skip'
|
| 303 |
+
)
|
| 304 |
+
data_traces.append(d_orbital)
|
| 305 |
|
| 306 |
# Create figure
|
| 307 |
fig = go.Figure(data=data_traces)
|
|
|
|
| 379 |
fn=name_to_3d_molecule,
|
| 380 |
inputs=[
|
| 381 |
gr.Textbox(label="Chemical Name", placeholder="e.g., benzene, aspirin, caffeine, glucose"),
|
| 382 |
+
gr.Checkbox(label="Show Electron Orbitals (s, p, d shapes)", value=False, info="Toggle to see s-orbitals (spheres), p-orbitals (dumbbells), and d-orbitals (cloverleaf) around atoms")
|
| 383 |
],
|
| 384 |
outputs=[
|
| 385 |
gr.HTML(label="2D Structure"),
|
|
|
|
| 387 |
gr.Textbox(label="3D SDF Content (Optional - for external viewers)", lines=10, max_lines=20, visible=False)
|
| 388 |
],
|
| 389 |
api_name="name_to_molecule",
|
| 390 |
+
description="🔬 View 2D structure and interactive 3D molecule with atom labels. Click and drag to rotate, scroll to zoom! ✨ Enable 'Show Electron Orbitals' to see s-orbitals (spheres), p-orbitals (dumbbells), and d-orbitals (cloverleaf shapes).",
|
| 391 |
cache_examples=False,
|
| 392 |
+
examples=[
|
| 393 |
+
["benzene", False],
|
| 394 |
+
["benzene", True],
|
| 395 |
+
["water", True],
|
| 396 |
+
["aspirin", False],
|
| 397 |
+
["caffeine", True],
|
| 398 |
+
["glucose", False]
|
| 399 |
+
],
|
| 400 |
)
|
| 401 |
|
| 402 |
|