Skip to content

Commit a4aca09

Browse files
authored
Use optimade to convert ASE atoms to JSON (#22)
* Use JSON conversion for ASE atoms * Add optimade as dependency * Update quantum_espresso_workflow.py * Update quantum_espresso_workflow.py * Update quantum_espresso_workflow.py
1 parent d659066 commit a4aca09

File tree

2 files changed

+19
-41
lines changed

2 files changed

+19
-41
lines changed

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ dependencies:
1111
- xmlschema=3.4.3
1212
- jobflow=0.1.19
1313
- pygraphviz=1.14
14+
- optimade=1.2.3

quantum_espresso_workflow.py

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import os
23
import subprocess
34

@@ -7,14 +8,16 @@
78
from adis_tools.parsers import parse_pw
89
import matplotlib.pyplot as plt
910
import numpy as np
11+
from optimade.adapters.structures.ase import from_ase_atoms, get_ase_atoms
12+
from optimade.models.structures import StructureResourceAttributes, StructureResource
1013

1114

1215
def write_input(input_dict, working_directory="."):
1316
filename = os.path.join(working_directory, "input.pwi")
1417
os.makedirs(working_directory, exist_ok=True)
1518
write(
1619
filename=filename,
17-
images=Atoms(**input_dict["structure"]),
20+
images=json_to_ase(atoms_json=input_dict["structure"]),
1821
Crystal=True,
1922
kpts=input_dict["kpts"],
2023
input_data={
@@ -31,7 +34,7 @@ def write_input(input_dict, working_directory="."):
3134
def collect_output(working_directory="."):
3235
output = parse_pw(os.path.join(working_directory, "pwscf.xml"))
3336
return {
34-
"structure": atoms_to_json_dict(atoms=output["ase_structure"]),
37+
"structure": ase_to_json(atoms=output["ase_structure"]),
3538
"energy": output["energy"],
3639
"volume": output["ase_structure"].get_volume(),
3740
}
@@ -53,12 +56,12 @@ def calculate_qe(working_directory, input_dict):
5356
def generate_structures(structure, strain_lst):
5457
structure_lst = []
5558
for strain in strain_lst:
56-
structure_strain = Atoms(**structure)
59+
structure_strain = json_to_ase(atoms_json=structure)
5760
structure_strain.set_cell(
5861
structure_strain.cell * strain ** (1 / 3), scale_atoms=True
5962
)
6063
structure_lst.append(structure_strain)
61-
return {f"s_{i}": atoms_to_json_dict(atoms=s) for i, s in enumerate(structure_lst)}
64+
return {f"s_{i}": ase_to_json(atoms=s) for i, s in enumerate(structure_lst)}
6265

6366

6467
def plot_energy_volume_curve(volume_lst, energy_lst):
@@ -74,40 +77,14 @@ def get_bulk_structure(element, a, cubic):
7477
a=a,
7578
cubic=cubic,
7679
)
77-
return atoms_to_json_dict(atoms=ase_atoms)
78-
79-
80-
def atoms_to_json_dict(atoms):
81-
"""
82-
Convert an ASE Atoms object to a fully JSON-serializable dictionary
83-
that uses only Python base data types.
84-
85-
Parameters:
86-
-----------
87-
atoms : ase.Atoms
88-
The Atoms object to convert
89-
90-
Returns:
91-
--------
92-
dict
93-
A dictionary representation using only Python base types
94-
"""
95-
# Get the dictionary representation from ASE
96-
atoms_dict = atoms.todict()
97-
98-
# Create a new dictionary with JSON-serializable values
99-
json_dict = {}
100-
101-
# Convert numpy arrays to lists
102-
for key, value in atoms_dict.items():
103-
if isinstance(value, np.ndarray):
104-
# Convert numpy boolean values to Python booleans
105-
if value.dtype == np.bool_ or value.dtype == bool:
106-
json_dict[key] = value.tolist()
107-
# Convert numpy arrays of numbers to Python lists
108-
else:
109-
json_dict[key] = value.tolist()
110-
else:
111-
json_dict[key] = value
112-
113-
return json_dict
80+
return ase_to_json(atoms=ase_atoms)
81+
82+
83+
def ase_to_json(atoms):
84+
struct_opt = from_ase_atoms(atoms=atoms)
85+
return json.dumps(struct_opt.model_dump(mode="json"))
86+
87+
88+
def json_to_ase(atoms_json):
89+
structure_restore = StructureResourceAttributes.model_validate_json(atoms_json)
90+
return get_ase_atoms(optimade_structure=StructureResource(id="ase", attributes=structure_restore))

0 commit comments

Comments
 (0)