Spaces:
Running
Running
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +44 -4
src/streamlit_app.py
CHANGED
@@ -1219,13 +1219,14 @@ if atoms is not None:
|
|
1219 |
|
1220 |
elif "Optimization" in task: # Handles both Geometry and Cell+Geometry Opt
|
1221 |
opt_atoms_obj = FrechetCellFilter(calc_atoms) if task == "Cell + Geometry Optimization" else calc_atoms
|
1222 |
-
|
|
|
1223 |
if optimizer_type == "BFGS":
|
1224 |
-
opt = BFGS(opt_atoms_obj)
|
1225 |
elif optimizer_type == "LBFGS":
|
1226 |
-
opt = LBFGS(opt_atoms_obj)
|
1227 |
else: # FIRE
|
1228 |
-
opt = FIRE(opt_atoms_obj)
|
1229 |
|
1230 |
# opt.attach(streamlit_log, interval=1) # Removed lambda for simplicity if streamlit_log is defined correctly
|
1231 |
opt.attach(lambda: streamlit_log(opt), interval=1)
|
@@ -1287,6 +1288,45 @@ if atoms is not None:
|
|
1287 |
mime="chemical/x-xyz"
|
1288 |
)
|
1289 |
os.unlink(tmp_filepath_opt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1290 |
|
1291 |
except Exception as e:
|
1292 |
st.error(f"🔴 Calculation error: {str(e)}")
|
|
|
1219 |
|
1220 |
elif "Optimization" in task: # Handles both Geometry and Cell+Geometry Opt
|
1221 |
opt_atoms_obj = FrechetCellFilter(calc_atoms) if task == "Cell + Geometry Optimization" else calc_atoms
|
1222 |
+
# Create temporary trajectory file
|
1223 |
+
traj_filename = tempfile.NamedTemporaryFile(delete=False, suffix=".traj").name
|
1224 |
if optimizer_type == "BFGS":
|
1225 |
+
opt = BFGS(opt_atoms_obj, trajectory=traj_filename)
|
1226 |
elif optimizer_type == "LBFGS":
|
1227 |
+
opt = LBFGS(opt_atoms_obj, trajectory=traj_filename)
|
1228 |
else: # FIRE
|
1229 |
+
opt = FIRE(opt_atoms_obj, trajectory=traj_filename)
|
1230 |
|
1231 |
# opt.attach(streamlit_log, interval=1) # Removed lambda for simplicity if streamlit_log is defined correctly
|
1232 |
opt.attach(lambda: streamlit_log(opt), interval=1)
|
|
|
1288 |
mime="chemical/x-xyz"
|
1289 |
)
|
1290 |
os.unlink(tmp_filepath_opt)
|
1291 |
+
|
1292 |
+
# Convert trajectory to XYZ for download
|
1293 |
+
from ase.io import read
|
1294 |
+
|
1295 |
+
if os.path.exists(traj_filename):
|
1296 |
+
try:
|
1297 |
+
# Read trajectory and convert to XYZ
|
1298 |
+
trajectory = read(traj_filename, index=':') # Read all frames
|
1299 |
+
|
1300 |
+
# Create XYZ content
|
1301 |
+
trajectory_xyz = ""
|
1302 |
+
for i, atoms in enumerate(trajectory):
|
1303 |
+
trajectory_xyz += f"{len(atoms)}\n"
|
1304 |
+
# Try to get energy if available
|
1305 |
+
try:
|
1306 |
+
energy = atoms.get_potential_energy()
|
1307 |
+
trajectory_xyz += f"Step {i}: Energy = {energy:.6f} eV\n"
|
1308 |
+
except:
|
1309 |
+
trajectory_xyz += f"Step {i}: Optimization trajectory\n"
|
1310 |
+
|
1311 |
+
for atom in atoms:
|
1312 |
+
trajectory_xyz += f"{atom.symbol} {atom.position[0]:.6f} {atom.position[1]:.6f} {atom.position[2]:.6f}\n"
|
1313 |
+
|
1314 |
+
st.markdown("### Optimization Trajectory")
|
1315 |
+
st.write(f"Captured {len(trajectory)} optimization steps")
|
1316 |
+
|
1317 |
+
st.download_button(
|
1318 |
+
label="Download Optimization Trajectory (XYZ)",
|
1319 |
+
data=trajectory_xyz,
|
1320 |
+
file_name="optimization_trajectory.xyz",
|
1321 |
+
mime="chemical/x-xyz"
|
1322 |
+
)
|
1323 |
+
|
1324 |
+
except Exception as e:
|
1325 |
+
st.warning(f"Could not process trajectory: {e}")
|
1326 |
+
|
1327 |
+
finally:
|
1328 |
+
# Clean up trajectory file
|
1329 |
+
os.unlink(traj_filename)
|
1330 |
|
1331 |
except Exception as e:
|
1332 |
st.error(f"🔴 Calculation error: {str(e)}")
|