Skip to content

Commit 34608d0

Browse files
Add custom as_dict/from_dict method for proper initialization of attributes of IcohpCollection (#4391)
* add custom from_dict method for proper initialization of attributes * pre-commit auto-fixes * add custom as_dict method for proper serialization * adapt existing test to check for serialization --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 20afc86 commit 34608d0

File tree

2 files changed

+79
-10
lines changed

2 files changed

+79
-10
lines changed

src/pymatgen/electronic_structure/cohp.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,75 @@ def are_cobis(self) -> bool:
13871387
"""Whether this is COBI."""
13881388
return self._are_cobis
13891389

1390+
def as_dict(self) -> dict[str, Any]:
1391+
"""JSON-serializable dict representation of COHP."""
1392+
return {
1393+
"@module": type(self).__module__,
1394+
"@class": type(self).__name__,
1395+
"are_coops": self._are_coops,
1396+
"are_cobis": self._are_cobis,
1397+
"list_labels": self._list_labels,
1398+
"list_atom1": self._list_atom1,
1399+
"list_atom2": self._list_atom2,
1400+
"list_length": self._list_length,
1401+
"list_translation": self._list_translation,
1402+
"list_num": self._list_num,
1403+
"list_icohp": [{str(spin): value for spin, value in icohp.items()} for icohp in self._list_icohp],
1404+
"is_spin_polarized": self._is_spin_polarized,
1405+
"list_orb_icohp": [
1406+
{
1407+
key: {
1408+
"icohp": {str(spin): value for spin, value in val["icohp"].items()},
1409+
"orbitals": [[n, int(orb)] for n, orb in val["orbitals"]],
1410+
}
1411+
for key, val in entry.items()
1412+
}
1413+
for entry in self._list_orb_icohp
1414+
],
1415+
}
1416+
1417+
@classmethod
1418+
def from_dict(cls, dct: dict[str, Any]) -> Self:
1419+
"""Generate IcohpCollection from a dict representation."""
1420+
list_icohp = []
1421+
for icohp_dict in dct["list_icohp"]:
1422+
new_icohp_dict = {}
1423+
for spin_key, value in icohp_dict.items():
1424+
# Convert string/int to Spin enum
1425+
spin_enum = (
1426+
Spin(int(spin_key)) if isinstance(spin_key, int) or spin_key in ("1", "-1") else Spin[spin_key]
1427+
)
1428+
new_icohp_dict[spin_enum] = value
1429+
list_icohp.append(new_icohp_dict)
1430+
1431+
new_list_orb = [{orb_label: {} for orb_label in bond} for bond in dct["list_orb_icohp"]] # type:ignore[var-annotated]
1432+
for bond_num, lab_orb_icohp in enumerate(dct["list_orb_icohp"]):
1433+
for orb in lab_orb_icohp:
1434+
for key in lab_orb_icohp[orb]:
1435+
sub_dict = {}
1436+
if key == "icohp":
1437+
sub_dict[key] = {
1438+
Spin.up: lab_orb_icohp[orb][key]["1"],
1439+
Spin.down: lab_orb_icohp[orb][key]["-1"],
1440+
}
1441+
1442+
if key == "orbitals":
1443+
orb_temp = []
1444+
1445+
for item in lab_orb_icohp[orb][key]:
1446+
item[1] = Orbital(item[1])
1447+
orb_temp.append(item)
1448+
sub_dict[key] = orb_temp # type: ignore[assignment]
1449+
1450+
new_list_orb[bond_num][orb].update(sub_dict)
1451+
1452+
dct["list_icohp"] = list_icohp
1453+
dct["list_orb_icohp"] = new_list_orb
1454+
1455+
init_dict = {k: v for k, v in dct.items() if "@" not in k}
1456+
1457+
return cls(**init_dict)
1458+
13901459

13911460
def get_integrated_cohp_in_energy_range(
13921461
cohp: CompleteCohp,

tests/electronic_structure/test_cohp.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,29 +235,29 @@ def setup_method(self):
235235
"list_translation": [[0, 0, -1], [0, 0, 0]],
236236
"list_num": [1, 1],
237237
"list_icohp": [
238-
{Spin.up: 0.29324, Spin.down: 0.29324},
239-
{Spin.up: 0.29324, Spin.down: 0.29324},
238+
{"1": 0.29324, "-1": 0.29324},
239+
{"1": 0.29324, "-1": 0.29324},
240240
],
241241
"is_spin_polarized": True,
242242
"list_orb_icohp": [
243243
{
244244
"2s-6s": {
245-
"icohp": {Spin.up: 0.0247, Spin.down: 0.0247},
246-
"orbitals": [[2, Orbital.s], [6, Orbital.s]],
245+
"icohp": {"1": 0.0247, "-1": 0.0247},
246+
"orbitals": [[2, 0], [6, 0]],
247247
},
248248
"2s-5py": {
249-
"icohp": {Spin.up: 8e-05, Spin.down: 8e-05},
250-
"orbitals": [[2, Orbital.s], [5, Orbital.py]],
249+
"icohp": {"1": 8e-05, "-1": 8e-05},
250+
"orbitals": [[2, 0], [5, 1]],
251251
},
252252
},
253253
{
254254
"2s-6s": {
255-
"icohp": {Spin.up: 0.0247, Spin.down: 0.0247},
256-
"orbitals": [[2, Orbital.s], [6, Orbital.s]],
255+
"icohp": {"1": 0.0247, "-1": 0.0247},
256+
"orbitals": [[2, 0], [6, 0]],
257257
},
258258
"2s-5py": {
259-
"icohp": {Spin.up: 0.5, Spin.down: 0},
260-
"orbitals": [[2, Orbital.s], [5, Orbital.py]],
259+
"icohp": {"1": 0.5, "-1": 0},
260+
"orbitals": [[2, 0], [5, 1]],
261261
},
262262
},
263263
],

0 commit comments

Comments
 (0)