Spaces:
Runtime error
Runtime error
Switch from Volume to Isosurface for better orbital visualization rendering
Browse files- app.py +58 -24
- force_rebuild.txt +1 -1
app.py
CHANGED
|
@@ -249,58 +249,92 @@ def smiles_to_molecular_orbitals(smiles_input: str, name_input: str) -> str:
|
|
| 249 |
# Parse cube file
|
| 250 |
x, y, z, values = parse_cube_file(cube_file)
|
| 251 |
|
| 252 |
-
# Create
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
value=values.flatten(),
|
| 258 |
-
isomin
|
| 259 |
-
isomax=
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
))
|
| 265 |
|
| 266 |
# Add molecular structure
|
| 267 |
atom_x, atom_y, atom_z = [], [], []
|
| 268 |
atom_colors = []
|
|
|
|
| 269 |
for atom in mol_3d.GetAtoms():
|
| 270 |
pos = mol_3d.GetConformer().GetAtomPosition(atom.GetIdx())
|
| 271 |
atom_x.append(pos.x)
|
| 272 |
atom_y.append(pos.y)
|
| 273 |
atom_z.append(pos.z)
|
|
|
|
| 274 |
# Color by atom type
|
| 275 |
if atom.GetSymbol() == 'C':
|
| 276 |
-
atom_colors.append('
|
| 277 |
elif atom.GetSymbol() == 'N':
|
| 278 |
-
atom_colors.append('
|
| 279 |
elif atom.GetSymbol() == 'O':
|
| 280 |
-
atom_colors.append('
|
| 281 |
elif atom.GetSymbol() == 'H':
|
| 282 |
-
atom_colors.append('
|
| 283 |
else:
|
| 284 |
-
atom_colors.append('
|
| 285 |
|
| 286 |
fig.add_trace(go.Scatter3d(
|
| 287 |
x=atom_x, y=atom_y, z=atom_z,
|
| 288 |
-
mode='markers',
|
| 289 |
-
marker=dict(size=
|
|
|
|
|
|
|
|
|
|
| 290 |
name='Atoms'
|
| 291 |
))
|
| 292 |
|
| 293 |
fig.update_layout(
|
| 294 |
-
title=f'{label} Orbital',
|
| 295 |
-
width=
|
| 296 |
height=600,
|
| 297 |
scene=dict(
|
| 298 |
xaxis_title='X (Å)',
|
| 299 |
yaxis_title='Y (Å)',
|
| 300 |
zaxis_title='Z (Å)',
|
| 301 |
-
aspectmode='data'
|
|
|
|
|
|
|
|
|
|
| 302 |
),
|
| 303 |
-
margin=dict(l=0, r=0, t=40, b=0)
|
|
|
|
|
|
|
| 304 |
)
|
| 305 |
|
| 306 |
# Generate HTML with config
|
|
@@ -308,10 +342,10 @@ def smiles_to_molecular_orbitals(smiles_input: str, name_input: str) -> str:
|
|
| 308 |
config = {
|
| 309 |
'displayModeBar': True,
|
| 310 |
'displaylogo': False,
|
| 311 |
-
'
|
| 312 |
}
|
| 313 |
plot_html = pio.to_html(fig, full_html=False, include_plotlyjs='cdn', config=config)
|
| 314 |
-
html_sections.append(f"<div style='margin: 20px 0;'
|
| 315 |
|
| 316 |
if not html_sections:
|
| 317 |
return "<p>Could not prepare HOMO/LUMO visualizations.</p>"
|
|
|
|
| 249 |
# Parse cube file
|
| 250 |
x, y, z, values = parse_cube_file(cube_file)
|
| 251 |
|
| 252 |
+
# Create 3D meshgrid
|
| 253 |
+
X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
|
| 254 |
+
|
| 255 |
+
# Create plotly figure with isosurface
|
| 256 |
+
fig = go.Figure()
|
| 257 |
+
|
| 258 |
+
# Add positive isosurface (blue)
|
| 259 |
+
fig.add_trace(go.Isosurface(
|
| 260 |
+
x=X.flatten(),
|
| 261 |
+
y=Y.flatten(),
|
| 262 |
+
z=Z.flatten(),
|
| 263 |
value=values.flatten(),
|
| 264 |
+
isomin=0.02,
|
| 265 |
+
isomax=values.max(),
|
| 266 |
+
surface_count=1,
|
| 267 |
+
colorscale=[[0, 'blue'], [1, 'blue']],
|
| 268 |
+
showscale=False,
|
| 269 |
+
caps=dict(x_show=False, y_show=False, z_show=False),
|
| 270 |
+
opacity=0.7,
|
| 271 |
+
name='Positive'
|
| 272 |
+
))
|
| 273 |
+
|
| 274 |
+
# Add negative isosurface (red)
|
| 275 |
+
fig.add_trace(go.Isosurface(
|
| 276 |
+
x=X.flatten(),
|
| 277 |
+
y=Y.flatten(),
|
| 278 |
+
z=Z.flatten(),
|
| 279 |
+
value=values.flatten(),
|
| 280 |
+
isomin=values.min(),
|
| 281 |
+
isomax=-0.02,
|
| 282 |
+
surface_count=1,
|
| 283 |
+
colorscale=[[0, 'red'], [1, 'red']],
|
| 284 |
+
showscale=False,
|
| 285 |
+
caps=dict(x_show=False, y_show=False, z_show=False),
|
| 286 |
+
opacity=0.7,
|
| 287 |
+
name='Negative'
|
| 288 |
))
|
| 289 |
|
| 290 |
# Add molecular structure
|
| 291 |
atom_x, atom_y, atom_z = [], [], []
|
| 292 |
atom_colors = []
|
| 293 |
+
atom_text = []
|
| 294 |
for atom in mol_3d.GetAtoms():
|
| 295 |
pos = mol_3d.GetConformer().GetAtomPosition(atom.GetIdx())
|
| 296 |
atom_x.append(pos.x)
|
| 297 |
atom_y.append(pos.y)
|
| 298 |
atom_z.append(pos.z)
|
| 299 |
+
atom_text.append(atom.GetSymbol())
|
| 300 |
# Color by atom type
|
| 301 |
if atom.GetSymbol() == 'C':
|
| 302 |
+
atom_colors.append('gray')
|
| 303 |
elif atom.GetSymbol() == 'N':
|
| 304 |
+
atom_colors.append('darkblue')
|
| 305 |
elif atom.GetSymbol() == 'O':
|
| 306 |
+
atom_colors.append('darkred')
|
| 307 |
elif atom.GetSymbol() == 'H':
|
| 308 |
+
atom_colors.append('lightgray')
|
| 309 |
else:
|
| 310 |
+
atom_colors.append('purple')
|
| 311 |
|
| 312 |
fig.add_trace(go.Scatter3d(
|
| 313 |
x=atom_x, y=atom_y, z=atom_z,
|
| 314 |
+
mode='markers+text',
|
| 315 |
+
marker=dict(size=10, color=atom_colors, line=dict(width=1, color='white')),
|
| 316 |
+
text=atom_text,
|
| 317 |
+
textposition='top center',
|
| 318 |
+
textfont=dict(size=8),
|
| 319 |
name='Atoms'
|
| 320 |
))
|
| 321 |
|
| 322 |
fig.update_layout(
|
| 323 |
+
title=dict(text=f'{label} Orbital', x=0.5, xanchor='center'),
|
| 324 |
+
width=700,
|
| 325 |
height=600,
|
| 326 |
scene=dict(
|
| 327 |
xaxis_title='X (Å)',
|
| 328 |
yaxis_title='Y (Å)',
|
| 329 |
zaxis_title='Z (Å)',
|
| 330 |
+
aspectmode='data',
|
| 331 |
+
camera=dict(
|
| 332 |
+
eye=dict(x=1.5, y=1.5, z=1.5)
|
| 333 |
+
)
|
| 334 |
),
|
| 335 |
+
margin=dict(l=0, r=0, t=40, b=0),
|
| 336 |
+
showlegend=True,
|
| 337 |
+
legend=dict(x=0.02, y=0.98)
|
| 338 |
)
|
| 339 |
|
| 340 |
# Generate HTML with config
|
|
|
|
| 342 |
config = {
|
| 343 |
'displayModeBar': True,
|
| 344 |
'displaylogo': False,
|
| 345 |
+
'responsive': True
|
| 346 |
}
|
| 347 |
plot_html = pio.to_html(fig, full_html=False, include_plotlyjs='cdn', config=config)
|
| 348 |
+
html_sections.append(f"<div style='margin: 20px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px;'>{plot_html}</div>")
|
| 349 |
|
| 350 |
if not html_sections:
|
| 351 |
return "<p>Could not prepare HOMO/LUMO visualizations.</p>"
|
force_rebuild.txt
CHANGED
|
@@ -1,2 +1,2 @@
|
|
| 1 |
# Force rebuild
|
| 2 |
-
2025-11-08
|
|
|
|
| 1 |
# Force rebuild
|
| 2 |
+
2025-11-08 v9
|