Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New class to handle NcICOBILIST.lobster files #2878

Merged
merged 45 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
63951e3
Implemented a pymatgen class to handle NcICOBILIST.lobster files
Mar 6, 2023
44b802d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 6, 2023
37e4101
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Mar 13, 2023
2b98329
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 13, 2023
a3f476d
checking lobster version
Mar 13, 2023
0aa3c96
Merge branch 'ncicobi' of https://github.com/QuantumChemist/pymatgen …
Mar 13, 2023
a08b88b
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Mar 14, 2023
4a56dc4
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist May 23, 2023
fdb2be2
pre-commit auto-fixes
pre-commit-ci[bot] May 23, 2023
c49dda1
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Jun 13, 2023
da8a14f
improved the tests for ncicobi
QuantumChemist Sep 22, 2023
6c3079c
merged and adapted to most recent pymatgen version
QuantumChemist Sep 22, 2023
9a94cf1
pre-commit auto-fixes
pre-commit-ci[bot] Sep 22, 2023
55a1b10
cleaned up the merge mess
QuantumChemist Sep 22, 2023
f00b4eb
cleaning up merging mess
QuantumChemist Sep 22, 2023
08c6afd
cleaning up merging mess
QuantumChemist Sep 22, 2023
8a42381
get the failing tests to work
QuantumChemist Sep 22, 2023
e0e3376
cleaning up merging mess
QuantumChemist Sep 22, 2023
450215d
Merge branch 'master' into ncicobi
QuantumChemist Sep 23, 2023
5b120c0
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Sep 24, 2023
438c21c
cleaning up merging
QuantumChemist Sep 25, 2023
42486dc
Merge branch 'ncicobi' of https://github.com/QuantumChemist/pymatgen …
QuantumChemist Sep 25, 2023
3bbd292
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Sep 28, 2023
348c3c7
Merge branch 'master' into ncicobi
QuantumChemist Sep 28, 2023
362df3e
Merge branch 'master' into ncicobi
QuantumChemist Sep 30, 2023
75dcb67
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Sep 30, 2023
97c94c3
adopted PascalCase for ncicobilist class
QuantumChemist Sep 30, 2023
0d61600
adopted PascalCase for ncicobilist class
QuantumChemist Sep 30, 2023
6fe669a
adopted PascalCase for ncicobilist class
QuantumChemist Sep 30, 2023
90bbec7
captitalized the wrong C
QuantumChemist Sep 30, 2023
9c2cf1e
Merge branch 'master' into ncicobi
QuantumChemist Oct 1, 2023
bfe4d99
snake_case
janosh Oct 1, 2023
6b7343d
use ternary for self.is_spin_polarized
janosh Oct 1, 2023
ca017b2
fix Attributes indentation
janosh Oct 1, 2023
30a27db
Merge branch 'materialsproject:master' into ncicobi
QuantumChemist Oct 2, 2023
dfb137d
commented why filename (NcICOBILIST.lobster) = None for LOBSTER versi…
QuantumChemist Oct 2, 2023
518ab48
pre-commit auto-fixes
pre-commit-ci[bot] Oct 2, 2023
f3fa91d
Merge branch 'master' into ncicobi
QuantumChemist Oct 4, 2023
1bd53b4
Update pymatgen/io/lobster/outputs.py
QuantumChemist Oct 4, 2023
25f703b
improved the code
QuantumChemist Oct 4, 2023
1227781
pre-commit auto-fixes
pre-commit-ci[bot] Oct 4, 2023
d2e4df0
get the linting check working
QuantumChemist Oct 4, 2023
97df4aa
get the linting check working
QuantumChemist Oct 4, 2023
84e5e48
Merge branch 'master' into ncicobi
QuantumChemist Oct 4, 2023
df6c5ba
pre-commit auto-fixes
pre-commit-ci[bot] Oct 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .attach_pid50466
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental commit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oopsie, sorry that was accidental. I created a mess when I merged the two versions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it now :)

Empty file.
1 change: 1 addition & 0 deletions pymatgen/io/lobster/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Icohplist,
Lobsterout,
MadelungEnergies,
Ncicobilist,
SitePotential,
Wavefunction,
)
112 changes: 110 additions & 2 deletions pymatgen/io/lobster/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@


class Cohpcar:
"""Class to read COHPCAR/COOPCAR files generated by LOBSTER.
"""
Class to read COHPCAR/COOPCAR/COBICAR files generated by LOBSTER.

Attributes:
cohp_data (dict[str, Dict[str, Any]]): A dictionary containing the COHP data of the form:
Expand Down Expand Up @@ -76,7 +77,7 @@ def __init__(self, are_coops: bool = False, are_cobis: bool = False, filename: s
Args:
are_coops: Determines if the file is a list of COHPs or COOPs.
Default is False for COHPs.
are_cobis: Determines if the file is a list of COHPs or COOPs.
are_cobis: Determines if the file is a list of COHPs or COBIs.
Default is False for COHPs.

filename: Name of the COHPCAR file. If it is None, the default
Expand Down Expand Up @@ -408,6 +409,113 @@ def icohpcollection(self):
return self._icohpcollection


class Ncicobilist:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not pascal case NciCobiList here? Easier to read imo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I wanted to stick to only capitalizing the first letter like in class Icohplist
For me NciCobilist is not very readable as the method referring to is NcICOBI, so maybe we can go with NcIcobilist or ncIcobilist ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @janosh, please let me know what you think about this. If it's not ok, I'm gonna adopt your suggestion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still prefer consistency with the rest of pymatgen which uses PascalCase for all class names. E.g. we have PotcarSingle and not POTCARSingle for that reason. But maybe another maintainer wants to chime in here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(It does not have to be consistent with the older Lobster class names.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@janosh, ok it's done :)))

"""
Class to read NcICOBILIST (multi-center ICOBI) files generated by LOBSTER.

Attributes:
is_spin_polarized (bool): Boolean to indicate if the calculation is spin polarized.
Ncicobilist (dict): Dict containing the listfile data of the form:
{bond: "number_of_atoms": number of atoms involved in the multi-center interaction,
"ncicobi": {Spin.up: Nc-ICOBI(Ef) spin up, Spin.down: ...}},
"interaction_type": type of the multi-center interaction
"""

def __init__(self, filename: str | None = None):
QuantumChemist marked this conversation as resolved.
Show resolved Hide resolved
"""
Args:
filename: Name of the NcICOBILIST file.
"""

if filename is None:
warnings.warn("Please consider using the newest LOBSTER version (4.1.0+). See http://www.cohp.de/.")
Copy link
Member

@janosh janosh Oct 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this warning correctly indented? Why only warn if filename is None?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like a leftover from the icohplist. I remember implementing this (with another if clause). I guess this can be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't you still use the default naming option in such a case and then then the file wouldn't be there? Thus, shouldn't it be the warning if the default file name does not exist rather than when it is set to None?

filename = "NcICOBILIST.lobster"

# LOBSTER list files have an extra trailing blank line
# and we don't need the header.
with zopen(filename, "rt") as f:
data = f.read().split("\n")[1:-1]
if len(data) == 0:
raise OSError("NcICOBILIST file contains no data.")

# If the calculation is spin polarized, the line in the middle
# of the file will be another header line.
if "spin" in data[len(data) // 2]:
# TODO: adapt this for orbitalwise stuff
self.is_spin_polarized = True
else:
self.is_spin_polarized = False

# check if orbitalwise NcICOBILIST
# include case when there is only one NcICOBI
for entry in data: # NcICOBIs orbitalwise and non-orbitalwise can be mixed
if len(data) > 2 and "s]" in str(entry.split()[3:]):
self.orbitalwise = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is self.orbitalwise missing a default value of False? Tests are currently failing with

AttributeError: 'NciCobiList' object has no attribute 'orbitalwise'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I have to look more into this... :O

warnings.warn(
"This is an orbitalwise NcICOBILIST.lobster file. Currently, the orbitalwise information is not "
"read!"
)
break # condition has only to be met once

if self.orbitalwise:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename to self.orbital_wise for readability?

data_without_orbitals = []
for line in data:
if "_" not in str(line.split()[3:]) and "s]" not in str(line.split()[3:]):
data_without_orbitals.append(line)
else:
data_without_orbitals = data

if "spin" in data_without_orbitals[len(data_without_orbitals) // 2]:
# TODO: adapt this for orbitalwise stuff
num_bonds = len(data_without_orbitals) // 2
if num_bonds == 0:
raise OSError("NcICOBILIST file contains no data.")
else:
num_bonds = len(data_without_orbitals)

self.list_labels = []
self.list_numofatoms = []
self.list_ncicobi = []
self.list_interactiontype = []
self.list_num = []

for bond in range(num_bonds):
line = data_without_orbitals[bond].split()
ncicobi = {}

label = f"{line[0]}"
numofatoms = str(line[1])
ncicobi[Spin.up] = float(line[2])
interactiontype = str(line[3:]).replace("'", "").replace(" ", "")
num = 1

if self.is_spin_polarized:
ncicobi[Spin.down] = float(data_without_orbitals[bond + num_bonds + 1].split()[2])

self.list_labels.append(label)
self.list_numofatoms.append(numofatoms)
self.list_ncicobi.append(ncicobi)
self.list_interactiontype.append(interactiontype)
self.list_num.append(num)

# TODO: add functions to get orbital resolved NcICOBIs

@property
def ncicobilist(self) -> dict[Any, dict[str, Any]]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename to def ncicobi_list()?

"""
Returns: ncicobilist.
"""
ncicobilist = {}
for key, _entry in enumerate(self.list_labels):
ncicobilist[str(key + 1)] = {
"number_of_atoms": int(self.list_numofatoms[key]),
"ncicobi": self.list_ncicobi[key],
"interaction_type": self.list_interactiontype[key],
}

return ncicobilist


class Doscar:
"""
Class to deal with Lobster's projected DOS and local projected DOS.
Expand Down
50 changes: 50 additions & 0 deletions test_files/cohp/NcICOBILIST.lobster
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, are new test files strictly necessary here? And if so, can they be compressed?

There are some that look like they could potentially be re-used:

$ ls tests/files/** | grep COBILIST
ICOBILIST.lobster
ICOBILIST.lobster.additional_case
ICOBILIST.lobster.spinpolarized
ICOBILIST.lobster.spinpolarized.additional_case
ICOBILIST.lobster.withoutorbitals

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The files mentioned here are not the ones I need. Seems that they haven't been fetched in the merge process. I gonna upload them quickly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh now I see with the merging process they have just been added to test_files/cohp (so like it was structured before). I gonna fix that now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the files in question are

$ ls tests/files/** | grep NcICOBI
NcICOBILIST.lobster
NcICOBILIST.lobster.gz
NcICOBILIST.lobster.nospin
NcICOBILIST.lobster.nospin.withoutorbitals
NcICOBILIST.lobster.withoutorbitals

please let me know if you see something unnecessary. From my POV this is the least user cases that should be checked.
Thank you for helping me with this PR :)

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
COBI# No. of atoms Nc-ICOBI (at) eF for spin 1 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X20 0 0]
2 3 0.00009 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
2 3 0.00116 X22[5s]->Xs42[3s]->X31[5s]
2 3 0.00001 X22[5s]->Xs42[3s]->X31[4d_xy]
2 3 -0.00003 X22[5s]->Xs42[3s]->X31[4d_yz]
2 3 -0.00000 X22[5s]->Xs42[3s]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3s]->X31[4d_xz]
2 3 0.00001 X22[5s]->Xs42[3s]->X31[4d_x^2-y^2]
2 3 0.00117 X22[5s]->Xs42[3p_y]->X31[5s]
2 3 -0.00002 X22[5s]->Xs42[3p_y]->X31[4d_xy]
2 3 -0.00003 X22[5s]->Xs42[3p_y]->X31[4d_yz]
2 3 0.00001 X22[5s]->Xs42[3p_y]->X31[4d_z^2]
2 3 -0.00000 X22[5s]->Xs42[3p_y]->X31[4d_xz]
2 3 0.00003 X22[5s]->Xs42[3p_y]->X31[4d_x^2-y^2]
2 3 -0.00071 X22[5s]->Xs42[3p_z]->X31[5s]
2 3 -0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xy]
2 3 0.00004 X22[5s]->Xs42[3p_z]->X31[4d_yz]
2 3 -0.00002 X22[5s]->Xs42[3p_z]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xz]
2 3 -0.00002 X22[5s]->Xs42[3p_z]->X31[4d_x^2-y^2]
2 3 -0.00149 X22[5s]->Xs42[3p_x]->X31[5s]
2 3 0.00000 X22[4d_x^2-y^2]->Xs42[3p]->X31[4d_x^2-y^2]
2 3 -0.00007 X22[4d_x^2-y^2]->Xs42[3p_y]->X31[5s]
2 3 0.00016 X22[4d_x^2-y^2]->Xs42[3p_x]->X31[5s]
COBI# No. of atoms Nc-ICOBI (at) eF for spin 2 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X2[0 0 0]
2 3 0.00009 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
2 3 0.00116 X22[5s]->Xs42[3s]->X31[5s]
2 3 0.00001 X22[5s]->Xs42[3s]->X31[4d_xy]
2 3 -0.00003 X22[5s]->Xs42[3s]->X31[4d_yz]
2 3 -0.00000 X22[5s]->Xs42[3s]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3s]->X31[4d_xz]
2 3 0.00001 X22[5s]->Xs42[3s]->X31[4d_x^2-y^2]
2 3 0.00117 X22[5s]->Xs42[3p_y]->X31[5s]
2 3 -0.00002 X22[5s]->Xs42[3p_y]->X31[4d_xy]
2 3 -0.00003 X22[5s]->Xs42[3p_y]->X31[4d_yz]
2 3 0.00001 X22[5s]->Xs42[3p_y]->X31[4d_z^2]
2 3 -0.00000 X22[5s]->Xs42[3p_y]->X31[4d_xz]
2 3 0.00003 X22[5s]->Xs42[3p_y]->X31[4d_x^2-y^2]
2 3 -0.00071 X22[5s]->Xs42[3p_z]->X31[5s]
2 3 -0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xy]
2 3 0.00004 X22[5s]->Xs42[3p_z]->X31[4d_yz]
2 3 -0.00002 X22[5s]->Xs42[3p_z]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xz]
2 3 -0.00002 X22[5s]->Xs42[3p_z]->X31[4d_x^2-y^2]
2 3 -0.00149 X22[5s]->Xs42[3p_x]->X31[5s]
2 3 0.00000 X22[4d_x^2-y^2]->Xs42[3p]->X31[4d_x^2-y^2]
2 3 -0.00007 X22[4d_x^2-y^2]->Xs42[3p_y]->X31[5s]
2 3 0.00016 X22[4d_x^2-y^2]->Xs42[3p_x]->X31[5s]
Binary file added test_files/cohp/NcICOBILIST.lobster.gz
Binary file not shown.
25 changes: 25 additions & 0 deletions test_files/cohp/NcICOBILIST.lobster.nospin
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
COBI# No. of atoms Nc-ICOBI (at) eF for spin 1 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X20 0 0]
2 3 0.00018 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
2 3 0.00232 X22[5s]->Xs42[3s]->X31[5s]
2 3 0.00002 X22[5s]->Xs42[3s]->X31[4d_xy]
2 3 -0.00006 X22[5s]->Xs42[3s]->X31[4d_yz]
2 3 -0.00000 X22[5s]->Xs42[3s]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3s]->X31[4d_xz]
2 3 0.00002 X22[5s]->Xs42[3s]->X31[4d_x^2-y^2]
2 3 0.00234 X22[5s]->Xs42[3p_y]->X31[5s]
2 3 -0.00004 X22[5s]->Xs42[3p_y]->X31[4d_xy]
2 3 -0.00006 X22[5s]->Xs42[3p_y]->X31[4d_yz]
2 3 0.00002 X22[5s]->Xs42[3p_y]->X31[4d_z^2]
2 3 -0.00000 X22[5s]->Xs42[3p_y]->X31[4d_xz]
2 3 0.00006 X22[5s]->Xs42[3p_y]->X31[4d_x^2-y^2]
2 3 -0.00142 X22[5s]->Xs42[3p_z]->X31[5s]
2 3 -0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xy]
2 3 0.00008 X22[5s]->Xs42[3p_z]->X31[4d_yz]
2 3 -0.00004 X22[5s]->Xs42[3p_z]->X31[4d_z^2]
2 3 0.00000 X22[5s]->Xs42[3p_z]->X31[4d_xz]
2 3 -0.00004 X22[5s]->Xs42[3p_z]->X31[4d_x^2-y^2]
2 3 -0.00298 X22[5s]->Xs42[3p_x]->X31[5s]
2 3 0.00000 X22[4d_x^2-y^2]->Xs42[3p]->X31[4d_x^2-y^2]
2 3 -0.00014 X22[4d_x^2-y^2]->Xs42[3p_y]->X31[5s]
2 3 0.00032 X22[4d_x^2-y^2]->Xs42[3p_x]->X31[5s]
3 changes: 3 additions & 0 deletions test_files/cohp/NcICOBILIST.lobster.nospin.withoutorbitals
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
COBI# No. of atoms Nc-ICOBI (at) eF for spin 1 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X20 0 0]
2 3 0.00018 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
6 changes: 6 additions & 0 deletions test_files/cohp/NcICOBILIST.lobster.withoutorbitals
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
COBI# No. of atoms Nc-ICOBI (at) eF for spin 1 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X20 0 0]
2 3 0.00009 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
COBI# No. of atoms Nc-ICOBI (at) eF for spin 2 Atoms for Nc-ICOBI
1 2 0.00000 X1[0 0 0]->X2[0 0 0]
2 3 0.00009 X22[0 0 0]->Xs42[0 0 0]->X31[0 0 0]
31 changes: 31 additions & 0 deletions tests/io/lobster/test_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
Lobsterin,
Lobsterout,
MadelungEnergies,
Ncicobilist,
SitePotential,
Wavefunction,
)
Expand Down Expand Up @@ -670,6 +671,36 @@ def test_values(self):
assert self.icobi_orbitalwise_spinpolarized.icohplist["2"]["orbitals"]["2s-6s"]["icohp"][Spin.up] == 0.0247


class TestNcicobilist(unittest.TestCase):
def setUp(self):
self.ncicobi = Ncicobilist(filename=f"{TEST_FILES_DIR}/cohp/NcICOBILIST.lobster")
self.ncicobigz = Ncicobilist(filename=f"{TEST_FILES_DIR}/cohp/NcICOBILIST.lobster.gz")
self.ncicobinospin = Ncicobilist(filename=f"{TEST_FILES_DIR}/cohp/NcICOBILIST.lobster.nospin")
self.ncicobinospinwo = Ncicobilist(filename=f"{TEST_FILES_DIR}/cohp/NcICOBILIST.lobster.nospin.withoutorbitals")
self.ncicobiwo = Ncicobilist(filename=f"{TEST_FILES_DIR}/cohp/NcICOBILIST.lobster.withoutorbitals")

def test_ncicobilist(self):
assert self.ncicobi.is_spin_polarized
assert not self.ncicobinospin.is_spin_polarized
assert self.ncicobiwo.is_spin_polarized
assert not self.ncicobinospinwo.is_spin_polarized
assert self.ncicobi.orbitalwise
assert self.ncicobinospin.orbitalwise
assert not self.ncicobiwo.orbitalwise
assert not self.ncicobinospinwo.orbitalwise
assert len(self.ncicobi.ncicobilist) == 2
assert self.ncicobi.ncicobilist["2"]["number_of_atoms"] == 3
assert self.ncicobi.ncicobilist["2"]["ncicobi"][Spin.up] == approx(0.00009)
assert self.ncicobi.ncicobilist["2"]["ncicobi"][Spin.down] == approx(0.00009)
assert self.ncicobi.ncicobilist["2"]["interaction_type"] == "[X22[0,0,0]->Xs42[0,0,0]->X31[0,0,0]]"
assert self.ncicobi.ncicobilist["2"]["ncicobi"][Spin.up] == self.ncicobiwo.ncicobilist["2"]["ncicobi"][Spin.up]
assert self.ncicobi.ncicobilist["2"]["ncicobi"][Spin.up] == self.ncicobigz.ncicobilist["2"]["ncicobi"][Spin.up]
assert self.ncicobi.ncicobilist["2"]["interaction_type"] == self.ncicobigz.ncicobilist["2"]["interaction_type"]
assert sum(list(self.ncicobi.ncicobilist["2"]["ncicobi"].values())) == approx(
self.ncicobinospin.ncicobilist["2"]["ncicobi"][Spin.up]
)


class TestDoscar(unittest.TestCase):
def setUp(self):
# first for spin polarized version
Expand Down