1
+ import json
1
2
import os
2
3
import subprocess
3
4
7
8
from adis_tools .parsers import parse_pw
8
9
import matplotlib .pyplot as plt
9
10
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
10
13
11
14
12
15
def write_input (input_dict , working_directory = "." ):
13
16
filename = os .path .join (working_directory , "input.pwi" )
14
17
os .makedirs (working_directory , exist_ok = True )
15
18
write (
16
19
filename = filename ,
17
- images = Atoms ( ** input_dict ["structure" ]),
20
+ images = json_to_ase ( atoms_json = input_dict ["structure" ]),
18
21
Crystal = True ,
19
22
kpts = input_dict ["kpts" ],
20
23
input_data = {
@@ -31,7 +34,7 @@ def write_input(input_dict, working_directory="."):
31
34
def collect_output (working_directory = "." ):
32
35
output = parse_pw (os .path .join (working_directory , "pwscf.xml" ))
33
36
return {
34
- "structure" : atoms_to_json_dict (atoms = output ["ase_structure" ]),
37
+ "structure" : ase_to_json (atoms = output ["ase_structure" ]),
35
38
"energy" : output ["energy" ],
36
39
"volume" : output ["ase_structure" ].get_volume (),
37
40
}
@@ -53,12 +56,12 @@ def calculate_qe(working_directory, input_dict):
53
56
def generate_structures (structure , strain_lst ):
54
57
structure_lst = []
55
58
for strain in strain_lst :
56
- structure_strain = Atoms ( ** structure )
59
+ structure_strain = json_to_ase ( atoms_json = structure )
57
60
structure_strain .set_cell (
58
61
structure_strain .cell * strain ** (1 / 3 ), scale_atoms = True
59
62
)
60
63
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 )}
62
65
63
66
64
67
def plot_energy_volume_curve (volume_lst , energy_lst ):
@@ -74,40 +77,14 @@ def get_bulk_structure(element, a, cubic):
74
77
a = a ,
75
78
cubic = cubic ,
76
79
)
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