text: # coding: utf-8
  # Copyright (c) Pymatgen Development Team.
  # Distributed under the terms of the MIT License.
  
  import json
  import os
  import tempfile
  import unittest
  import warnings
  
  import numpy as np
  
  from pymatgen import Structure
  from pymatgen.electronic_structure.core import Spin, Orbital
  from pymatgen.io.lobster import Cohpcar, Icohplist, Doscar, Charge, Lobsterout, Fatband, Lobsterin, Bandoverlaps, \
      Grosspop
  from pymatgen.io.lobster.inputs import get_all_possible_basis_combinations
  from pymatgen.io.vasp import Vasprun
  from pymatgen.io.vasp.inputs import Incar, Kpoints, Potcar
  from pymatgen.util.testing import PymatgenTest
  
  __author__ = "Janine George, Marco Esters"
  __copyright__ = "Copyright 2017, The Materials Project"
  __version__ = "0.2"
  __email__ = "janine.george@uclouvain.be, esters@uoregon.edu"
  __date__ = "Dec 10, 2017"
  
  test_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                          "..", "..", "..", "..", "test_files", "cohp")
  test_dir_doscar = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 "..", "..", "..", "..", "test_files")
  
  this_dir = os.path.dirname(os.path.abspath(__file__))
  
  
  class CohpcarTest(PymatgenTest):
      def setUp(self):
          self.cohp_bise = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.BiSe"))
          self.coop_bise = Cohpcar(filename=os.path.join(test_dir, "COOPCAR.lobster.BiSe"),
                                   are_coops=True)
          self.cohp_fe = Cohpcar(filename=os.path.join(test_dir, "COOPCAR.lobster"))
          self.coop_fe = Cohpcar(filename=os.path.join(test_dir, "COOPCAR.lobster"), are_coops=True)
          self.orb = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.orbitalwise"))
          self.orb_notot = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.notot.orbitalwise"))
  
          # Lobster 3.1 (Test data is from prerelease of Lobster 3.1)
          self.cohp_KF = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.KF"))
          self.coop_KF = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.KF"), are_coops=True)
  
          # example with f electrons
          self.cohp_Na2UO4 = Cohpcar(filename=os.path.join(test_dir, "COHPCAR.lobster.Na2UO4"))
          self.coop_Na2UO4 = Cohpcar(filename=os.path.join(test_dir, "COOPCAR.lobster.Na2UO4"), are_coops=True)
  
      def test_attributes(self):
          self.assertFalse(self.cohp_bise.are_coops)
          self.assertTrue(self.coop_bise.are_coops)
          self.assertFalse(self.cohp_bise.is_spin_polarized)
          self.assertFalse(self.coop_bise.is_spin_polarized)
          self.assertFalse(self.cohp_fe.are_coops)
          self.assertTrue(self.coop_fe.are_coops)
          self.assertTrue(self.cohp_fe.is_spin_polarized)
          self.assertTrue(self.coop_fe.is_spin_polarized)
          self.assertEqual(len(self.cohp_bise.energies), 241)
          self.assertEqual(len(self.coop_bise.energies), 241)
          self.assertEqual(len(self.cohp_fe.energies), 301)
          self.assertEqual(len(self.coop_fe.energies), 301)
          self.assertEqual(len(self.cohp_bise.cohp_data), 12)
          self.assertEqual(len(self.coop_bise.cohp_data), 12)
          self.assertEqual(len(self.cohp_fe.cohp_data), 3)
          self.assertEqual(len(self.coop_fe.cohp_data), 3)
  
          # Lobster 3.1
          self.assertFalse(self.cohp_KF.are_coops)
          self.assertTrue(self.coop_KF.are_coops)
          self.assertFalse(self.cohp_KF.is_spin_polarized)
          self.assertFalse(self.coop_KF.is_spin_polarized)
          self.assertEqual(len(self.cohp_KF.energies), 6)
          self.assertEqual(len(self.coop_KF.energies), 6)
          self.assertEqual(len(self.cohp_KF.cohp_data), 7)
          self.assertEqual(len(self.coop_KF.cohp_data), 7)
  
      def test_energies(self):
          efermi_bise = 5.90043
          elim_bise = (-0.124679, 11.9255)
          efermi_fe = 9.75576
          elim_fe = (-0.277681, 14.7725)
          efermi_KF = -2.87475
          elim_KF = (-11.25000 + efermi_KF, 7.5000 + efermi_KF)
  
          self.assertEqual(self.cohp_bise.efermi, efermi_bise)
          self.assertEqual(self.coop_bise.efermi, efermi_bise)
          self.assertEqual(self.cohp_fe.efermi, efermi_fe)
          self.assertEqual(self.coop_fe.efermi, efermi_fe)
          # Lobster 3.1
          self.assertEqual(self.cohp_KF.efermi, efermi_KF)
          self.assertEqual(self.coop_KF.efermi, efermi_KF)
  
          self.assertAlmostEqual(self.cohp_bise.energies[0]
                                 + self.cohp_bise.efermi, elim_bise[0],
                                 places=4)
          self.assertAlmostEqual(self.cohp_bise.energies[-1]
                                 + self.cohp_bise.efermi, elim_bise[1],
                                 places=4)
          self.assertAlmostEqual(self.coop_bise.energies[0]
                                 + self.coop_bise.efermi, elim_bise[0],
                                 places=4)
          self.assertAlmostEqual(self.coop_bise.energies[-1]
                                 + self.coop_bise.efermi, elim_bise[1],
                                 places=4)
  
          self.assertAlmostEqual(self.cohp_fe.energies[0] + self.cohp_fe.efermi,
                                 elim_fe[0], places=4)
          self.assertAlmostEqual(self.cohp_fe.energies[-1] + self.cohp_fe.efermi,
                                 elim_fe[1], places=4)
          self.assertAlmostEqual(self.coop_fe.energies[0] + self.coop_fe.efermi,
                                 elim_fe[0], places=4)
          self.assertAlmostEqual(self.coop_fe.energies[-1] + self.coop_fe.efermi,
                                 elim_fe[1], places=4)
  
          # Lobster 3.1
          self.assertAlmostEqual(self.cohp_KF.energies[0] + self.cohp_KF.efermi,
                                 elim_KF[0], places=4)
          self.assertAlmostEqual(self.cohp_KF.energies[-1] + self.cohp_KF.efermi,
                                 elim_KF[1], places=4)
          self.assertAlmostEqual(self.coop_KF.energies[0] + self.coop_KF.efermi,
                                 elim_KF[0], places=4)
          self.assertAlmostEqual(self.coop_KF.energies[-1] + self.coop_KF.efermi,
                                 elim_KF[1], places=4)
  
      def test_cohp_data(self):
          lengths_sites_bise = {"1": (2.882308829886294, (0, 6)),
                                "2": (3.1014396233274444, (0, 9)),
                                "3": (2.8823088298862083, (1, 7)),
                                "4": (3.1014396233275434, (1, 8)),
                                "5": (3.0500070394403904, (2, 9)),
                                "6": (2.9167594580335807, (2, 10)),
                                "7": (3.05000703944039, (3, 8)),
                                "8": (2.9167594580335803, (3, 11)),
                                "9": (3.3752173204052101, (4, 11)),
                                "10": (3.0729354518345948, (4, 5)),
                                "11": (3.3752173204052101, (5, 10))}
          lengths_sites_fe = {"1": (2.8318907764979082, (7, 6)),
                              "2": (2.4524893531900283, (7, 8))}
          # Lobster 3.1
          lengths_sites_KF = {"1": (2.7119923200622269, (0, 1)),
                              "2": (2.7119923200622269, (0, 1)),
                              "3": (2.7119923576010501, (0, 1)),
                              "4": (2.7119923576010501, (0, 1)),
                              "5": (2.7119923200622269, (0, 1)),
                              "6": (2.7119923200622269, (0, 1))}
  
          for data in [self.cohp_bise.cohp_data, self.coop_bise.cohp_data]:
              for bond in data:
                  if bond != "average":
                      self.assertEqual(data[bond]["length"],
                                       lengths_sites_bise[bond][0])
                      self.assertEqual(data[bond]["sites"],
                                       lengths_sites_bise[bond][1])
                      self.assertEqual(len(data[bond]["COHP"][Spin.up]), 241)
                      self.assertEqual(len(data[bond]["ICOHP"][Spin.up]), 241)
          for data in [self.cohp_fe.cohp_data, self.coop_fe.cohp_data]:
              for bond in data:
                  if bond != "average":
                      self.assertEqual(data[bond]["length"],
                                       lengths_sites_fe[bond][0])
                      self.assertEqual(data[bond]["sites"],
                                       lengths_sites_fe[bond][1])
                      self.assertEqual(len(data[bond]["COHP"][Spin.up]), 301)
                      self.assertEqual(len(data[bond]["ICOHP"][Spin.up]), 301)
  
          # Lobster 3.1
          for data in [self.cohp_KF.cohp_data, self.coop_KF.cohp_data]:
              for bond in data:
                  if bond != "average":
                      self.assertEqual(data[bond]["length"],
                                       lengths_sites_KF[bond][0])
                      self.assertEqual(data[bond]["sites"],
                                       lengths_sites_KF[bond][1])
                      self.assertEqual(len(data[bond]["COHP"][Spin.up]), 6)
                      self.assertEqual(len(data[bond]["ICOHP"][Spin.up]), 6)
  
      def test_orbital_resolved_cohp(self):
          orbitals = [tuple((Orbital(i), Orbital(j))) for j in range(4)
                      for i in range(4)]
          self.assertIsNone(self.cohp_bise.orb_res_cohp)
          self.assertIsNone(self.coop_bise.orb_res_cohp)
          self.assertIsNone(self.cohp_fe.orb_res_cohp)
          self.assertIsNone(self.coop_fe.orb_res_cohp)
          self.assertIsNone(self.orb_notot.cohp_data["1"]["COHP"])
          self.assertIsNone(self.orb_notot.cohp_data["1"]["ICOHP"])
          for orbs in self.orb.orb_res_cohp["1"]:
              orb_set = self.orb.orb_res_cohp["1"][orbs]["orbitals"]
              self.assertEqual(orb_set[0][0], 4)
              self.assertEqual(orb_set[1][0], 4)
              self.assertIn(tuple((orb_set[0][1], orb_set[1][1])), orbitals)
  
          # test d and f orbitals
          comparelist = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
                         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
                         7, 7, 7, 7]
          comparelist2 = ["f0", "f0", "f0", "f0", "f1", "f1", "f1", "f1", "f2", "f2", "f2", "f2", "f3", "f3", "f3", "f3",
                          "f_1", "f_1", "f_1", "f_1", "f_2", "f_2", "f_2", "f_2", "f_3", "f_3", "f_3", "f_3", "dx2",
                          "dx2", "dx2", "dx2", "dxy", "dxy", "dxy", "dxy", "dxz", "dxz", "dxz", "dxz", "dyz", "dyz",
                          "dyz", "dyz", "dz2", "dz2", "dz2", "dz2", "px", "px", "px", "px", "py", "py", "py", "py", "pz",
                          "pz", "pz", "pz", "s", "s", "s", "s", "s", "s", "s", "s"]
          for iorb, orbs in enumerate(sorted(self.cohp_Na2UO4.orb_res_cohp["49"])):
              orb_set = self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["orbitals"]
              self.assertEqual(orb_set[0][0], comparelist[iorb])
              self.assertEqual(str(orb_set[0][1]), comparelist2[iorb])
  
          # The sum of the orbital-resolved COHPs should be approximately
          # the total COHP. Due to small deviations in the LOBSTER calculation,
          # the precision is not very high though.
          cohp = self.orb.cohp_data["1"]["COHP"][Spin.up]
          icohp = self.orb.cohp_data["1"]["ICOHP"][Spin.up]
          tot = np.sum([self.orb.orb_res_cohp["1"][orbs]["COHP"][Spin.up]
                        for orbs in self.orb.orb_res_cohp["1"]], axis=0)
          self.assertArrayAlmostEqual(tot, cohp, decimal=3)
          tot = np.sum([self.orb.orb_res_cohp["1"][orbs]["ICOHP"][Spin.up]
                        for orbs in self.orb.orb_res_cohp["1"]], axis=0)
          self.assertArrayAlmostEqual(tot, icohp, decimal=3)
  
          # Lobster 3.1
          cohp_KF = self.cohp_KF.cohp_data["1"]["COHP"][Spin.up]
          icohp_KF = self.cohp_KF.cohp_data["1"]["ICOHP"][Spin.up]
          tot_KF = np.sum([self.cohp_KF.orb_res_cohp["1"][orbs]["COHP"][Spin.up]
                           for orbs in self.cohp_KF.orb_res_cohp["1"]], axis=0)
          self.assertArrayAlmostEqual(tot_KF, cohp_KF, decimal=3)
          tot_KF = np.sum([self.cohp_KF.orb_res_cohp["1"][orbs]["ICOHP"][Spin.up]
                           for orbs in self.cohp_KF.orb_res_cohp["1"]], axis=0)
          self.assertArrayAlmostEqual(tot_KF, icohp_KF, decimal=3)
  
          # d and f orbitals
          cohp_Na2UO4 = self.cohp_Na2UO4.cohp_data["49"]["COHP"][Spin.up]
          icohp_Na2UO4 = self.cohp_Na2UO4.cohp_data["49"]["ICOHP"][Spin.up]
          tot_Na2UO4 = np.sum([self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["COHP"][Spin.up]
                               for orbs in self.cohp_Na2UO4.orb_res_cohp["49"]], axis=0)
          self.assertArrayAlmostEqual(tot_Na2UO4, cohp_Na2UO4, decimal=3)
          tot_Na2UO4 = np.sum([self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["ICOHP"][Spin.up]
                               for orbs in self.cohp_Na2UO4.orb_res_cohp["49"]], axis=0)
          self.assertArrayAlmostEqual(tot_Na2UO4, icohp_Na2UO4, decimal=3)
  
  
  class IcohplistTest(unittest.TestCase):
      def setUp(self):
          self.icohp_bise = Icohplist(filename=os.path.join(test_dir, "ICOHPLIST.lobster.BiSe"))
          self.icoop_bise = Icohplist(filename=os.path.join(test_dir, "ICOOPLIST.lobster.BiSe"),
                                      are_coops=True)
          self.icohp_fe = Icohplist(filename=os.path.join(test_dir, "ICOHPLIST.lobster"))
          # allow gzipped files
          self.icohp_gzipped = Icohplist(filename=os.path.join(test_dir, "ICOHPLIST.lobster.gz"))
          self.icoop_fe = Icohplist(filename=os.path.join(test_dir, "ICOHPLIST.lobster"), are_coops=True)
  
      def test_attributes(self):
          self.assertFalse(self.icohp_bise.are_coops)
          self.assertTrue(self.icoop_bise.are_coops)
          self.assertFalse(self.icohp_bise.is_spin_polarized)
          self.assertFalse(self.icoop_bise.is_spin_polarized)
          self.assertEqual(len(self.icohp_bise.icohplist), 11)
          self.assertEqual(len(self.icoop_bise.icohplist), 11)
          self.assertFalse(self.icohp_fe.are_coops)
          self.assertTrue(self.icoop_fe.are_coops)
          self.assertTrue(self.icohp_fe.is_spin_polarized)
          self.assertTrue(self.icoop_fe.is_spin_polarized)
          self.assertEqual(len(self.icohp_fe.icohplist), 2)
          self.assertEqual(len(self.icoop_fe.icohplist), 2)
  
      def test_values(self):
          icohplist_bise = {"1": {"length": 2.88231, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -2.18042},
                                  "translation": [0, 0, 0]},
                            "2": {"length": 3.10144, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.14347},
                                  "translation": [0, 0, 0]},
                            "3": {"length": 2.88231, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -2.18042},
                                  "translation": [0, 0, 0]},
                            "4": {"length": 3.10144, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.14348},
                                  "translation": [0, 0, 0]},
                            "5": {"length": 3.05001, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.30006},
                                  "translation": [0, 0, 0]},
                            "6": {"length": 2.91676, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.96843},
                                  "translation": [0, 0, 0]},
                            "7": {"length": 3.05001, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.30006}, "translation": [0, 0, 0]},
                            "8": {"length": 2.91676, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -1.96843}, "translation": [0, 0, 0]},
                            "9": {"length": 3.37522, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.47531}, "translation": [0, 0, 0]},
                            "10": {"length": 3.07294, "number_of_bonds": 3,
                                   "icohp": {Spin.up: -2.38796}, "translation": [0, 0, 0]},
                            "11": {"length": 3.37522, "number_of_bonds": 3,
                                   "icohp": {Spin.up: -0.47531}, "translation": [0, 0, 0]}, }
          icooplist_bise = {"1": {"length": 2.88231, "number_of_bonds": 3,
                                  "icohp": {Spin.up: 0.14245}, "translation": [0, 0, 0]},
                            "2": {"length": 3.10144, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.04118}, "translation": [0, 0, 0]},
                            "3": {"length": 2.88231, "number_of_bonds": 3,
                                  "icohp": {Spin.up: 0.14245}, "translation": [0, 0, 0]},
                            "4": {"length": 3.10144, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.04118}, "translation": [0, 0, 0]},
                            "5": {"length": 3.05001, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.03516}, "translation": [0, 0, 0]},
                            "6": {"length": 2.91676, "number_of_bonds": 3,
                                  "icohp": {Spin.up: 0.10745}, "translation": [0, 0, 0]},
                            "7": {"length": 3.05001, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.03516}, "translation": [0, 0, 0]},
                            "8": {"length": 2.91676, "number_of_bonds": 3,
                                  "icohp": {Spin.up: 0.10745}, "translation": [0, 0, 0]},
                            "9": {"length": 3.37522, "number_of_bonds": 3,
                                  "icohp": {Spin.up: -0.12395}, "translation": [0, 0, 0]},
                            "10": {"length": 3.07294, "number_of_bonds": 3,
                                   "icohp": {Spin.up: 0.24714}, "translation": [0, 0, 0]},
                            "11": {"length": 3.37522, "number_of_bonds": 3,
                                   "icohp": {Spin.up: -0.12395}, "translation": [0, 0, 0]}}
          icooplist_fe = {'1': {'length': 2.83189, 'number_of_bonds': 2,
                                'icohp': {Spin.up: -0.10218, Spin.down: -0.19701},
                                'translation': [0, 0, 0]},
                          '2': {'length': 2.45249, 'number_of_bonds': 1,
                                'icohp': {Spin.up: -0.28485, Spin.down: -0.58279},
                                'translation': [0, 0, 0]}}
  
          self.assertEqual(icohplist_bise, self.icohp_bise.icohplist)
          self.assertEqual(icooplist_fe, self.icoop_fe.icohplist)
  
  
  class DoscarTest(unittest.TestCase):
      def setUp(self):
          # first for spin polarized version
          doscar = os.path.join(test_dir_doscar, "DOSCAR.lobster.spin")
          poscar = os.path.join(test_dir_doscar, "POSCAR.lobster.spin_DOS")
          # not spin polarized
          doscar2 = os.path.join(test_dir_doscar, "DOSCAR.lobster.nonspin")
          poscar2 = os.path.join(test_dir_doscar, "POSCAR.lobster.nonspin_DOS")
          self.DOSCAR_spin_pol = Doscar(doscar=doscar, structure_file=poscar)
          self.DOSCAR_nonspin_pol = Doscar(doscar=doscar2, structure_file=poscar2)
  
          with open(os.path.join(test_dir_doscar, 'structure_KF.json'), 'r') as f:
              data = json.load(f)
  
          self.structure = Structure.from_dict(data)
  
      def test_completedos(self):
          # first for spin polarized version
          energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
          tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
          tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
          fermi = 0.0
  
          PDOS_F_2s_up = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
          PDOS_F_2s_down = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
          PDOS_F_2py_up = [0.00000, 0.00160, 0.00000, 0.25801, 0.00000, 0.00029]
          PDOS_F_2py_down = [0.00000, 0.00161, 0.00000, 0.25819, 0.00000, 0.00029]
          PDOS_F_2pz_up = [0.00000, 0.00161, 0.00000, 0.25823, 0.00000, 0.00029]
          PDOS_F_2pz_down = [0.00000, 0.00160, 0.00000, 0.25795, 0.00000, 0.00029]
          PDOS_F_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029]
          PDOS_F_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029]
  
          self.assertListEqual(energies_spin, self.DOSCAR_spin_pol.completedos.energies.tolist())
          self.assertListEqual(tdos_up, self.DOSCAR_spin_pol.completedos.densities[Spin.up].tolist())
          self.assertListEqual(tdos_down, self.DOSCAR_spin_pol.completedos.densities[Spin.down].tolist())
          self.assertAlmostEqual(fermi, self.DOSCAR_spin_pol.completedos.efermi)
          for coords, coords2 in zip(self.DOSCAR_spin_pol.completedos.structure.frac_coords, self.structure.frac_coords):
              for xyz, xyz2 in zip(coords, coords2):
                  self.assertAlmostEqual(xyz, xyz2)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2s'][Spin.up].tolist(),
                               PDOS_F_2s_up)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2s'][Spin.down].tolist(),
                               PDOS_F_2s_down)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_y'][Spin.up].tolist(),
                               PDOS_F_2py_up)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_y'][Spin.down].tolist(),
                               PDOS_F_2py_down)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_z'][Spin.up].tolist(),
                               PDOS_F_2pz_up)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_z'][Spin.down].tolist(),
                               PDOS_F_2pz_down)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_x'][Spin.up].tolist(),
                               PDOS_F_2px_up)
          self.assertListEqual(self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]['2p_x'][Spin.down].tolist(),
                               PDOS_F_2px_down)
  
          energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
          tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
          PDOS_F_2s = [0.00000, 0.00320, 0.00000, 0.00017, 0.00000, 0.00060]
          PDOS_F_2py = [0.00000, 0.00322, 0.00000, 0.51635, 0.00000, 0.00037]
          PDOS_F_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037]
          PDOS_F_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037]
  
          self.assertListEqual(energies_nonspin, self.DOSCAR_nonspin_pol.completedos.energies.tolist())
  
          self.assertListEqual(tdos_nonspin, self.DOSCAR_nonspin_pol.completedos.densities[Spin.up].tolist())
  
          self.assertAlmostEqual(fermi, self.DOSCAR_nonspin_pol.completedos.efermi)
          self.assertDictEqual(self.DOSCAR_nonspin_pol.completedos.structure.as_dict(), self.structure.as_dict())
  
          self.assertListEqual(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]['2s'][Spin.up].tolist(),
                               PDOS_F_2s)
          self.assertListEqual(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]['2p_y'][Spin.up].tolist(),
                               PDOS_F_2py)
          self.assertListEqual(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]['2p_z'][Spin.up].tolist(),
                               PDOS_F_2pz)
          self.assertListEqual(self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]['2p_x'][Spin.up].tolist(),
                               PDOS_F_2px)
  
      def test_pdos(self):
          # first for spin polarized version
  
          PDOS_F_2s_up = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
          PDOS_F_2s_down = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
          PDOS_F_2py_up = [0.00000, 0.00160, 0.00000, 0.25801, 0.00000, 0.00029]
          PDOS_F_2py_down = [0.00000, 0.00161, 0.00000, 0.25819, 0.00000, 0.00029]
          PDOS_F_2pz_up = [0.00000, 0.00161, 0.00000, 0.25823, 0.00000, 0.00029]
          PDOS_F_2pz_down = [0.00000, 0.00160, 0.00000, 0.25795, 0.00000, 0.00029]
          PDOS_F_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029]
          PDOS_F_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029]
  
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2s'][Spin.up].tolist(),
                               PDOS_F_2s_up)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2s'][Spin.down].tolist(),
                               PDOS_F_2s_down)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_y'][Spin.up].tolist(),
                               PDOS_F_2py_up)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_y'][Spin.down].tolist(),
                               PDOS_F_2py_down)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_z'][Spin.up].tolist(),
                               PDOS_F_2pz_up)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_z'][Spin.down].tolist(),
                               PDOS_F_2pz_down)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_x'][Spin.up].tolist(),
                               PDOS_F_2px_up)
          self.assertListEqual(self.DOSCAR_spin_pol.pdos[0]['2p_x'][Spin.down].tolist(),
                               PDOS_F_2px_down)
  
          # non spin
          PDOS_F_2s = [0.00000, 0.00320, 0.00000, 0.00017, 0.00000, 0.00060]
          PDOS_F_2py = [0.00000, 0.00322, 0.00000, 0.51635, 0.00000, 0.00037]
          PDOS_F_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037]
          PDOS_F_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037]
  
          self.assertListEqual(self.DOSCAR_nonspin_pol.pdos[0]['2s'][Spin.up].tolist(), PDOS_F_2s)
          self.assertListEqual(self.DOSCAR_nonspin_pol.pdos[0]['2p_y'][Spin.up].tolist(), PDOS_F_2py)
          self.assertListEqual(self.DOSCAR_nonspin_pol.pdos[0]['2p_z'][Spin.up].tolist(), PDOS_F_2pz)
          self.assertListEqual(self.DOSCAR_nonspin_pol.pdos[0]['2p_x'][Spin.up].tolist(), PDOS_F_2px)
  
      def test_tdos(self):
          # first for spin polarized version
          energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
          tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
          tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
          fermi = 0.0
  
          self.assertListEqual(energies_spin, self.DOSCAR_spin_pol.tdos.energies.tolist())
          self.assertListEqual(tdos_up, self.DOSCAR_spin_pol.tdos.densities[Spin.up].tolist())
          self.assertListEqual(tdos_down, self.DOSCAR_spin_pol.tdos.densities[Spin.down].tolist())
          self.assertAlmostEqual(fermi, self.DOSCAR_spin_pol.tdos.efermi)
  
          energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
          tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
          fermi = 0.0
  
          self.assertListEqual(energies_nonspin, self.DOSCAR_nonspin_pol.tdos.energies.tolist())
          self.assertListEqual(tdos_nonspin, self.DOSCAR_nonspin_pol.tdos.densities[Spin.up].tolist())
          self.assertAlmostEqual(fermi, self.DOSCAR_nonspin_pol.tdos.efermi)
  
      def test_energies(self):
          # first for spin polarized version
          energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
  
          self.assertListEqual(energies_spin, self.DOSCAR_spin_pol.energies.tolist())
  
          energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
          self.assertListEqual(energies_nonspin, self.DOSCAR_nonspin_pol.energies.tolist())
  
      def test_tdensities(self):
          # first for spin polarized version
          tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
          tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
  
          self.assertListEqual(tdos_up, self.DOSCAR_spin_pol.tdensities[Spin.up].tolist())
          self.assertListEqual(tdos_down, self.DOSCAR_spin_pol.tdensities[Spin.down].tolist())
  
          tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
          self.assertListEqual(tdos_nonspin, self.DOSCAR_nonspin_pol.tdensities[Spin.up].tolist())
  
      def test_itdensities(self):
          pass
          itdos_up = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09650]
          itdos_down = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09685]
          self.assertListEqual(itdos_up, self.DOSCAR_spin_pol.itdensities[Spin.up].tolist())
          self.assertListEqual(itdos_down, self.DOSCAR_spin_pol.itdensities[Spin.down].tolist())
  
          itdos_nonspin = [4.00000, 10.00000, 10.00000, 16.00000, 16.00000, 16.09067]
          self.assertListEqual(itdos_nonspin, self.DOSCAR_nonspin_pol.itdensities[Spin.up].tolist())
  
      def test_is_spin_polarized(self):
          # first for spin polarized version
          self.assertTrue(self.DOSCAR_spin_pol.is_spin_polarized)
  
          self.assertFalse(self.DOSCAR_nonspin_pol.is_spin_polarized)
  
  
  class ChargeTest(PymatgenTest):
      def setUp(self):
          self.charge2 = Charge(filename=os.path.join(test_dir, "CHARGE.lobster.MnO"))
          # gzipped file
          self.charge = Charge(filename=os.path.join(test_dir, "CHARGE.lobster.MnO2.gz"))
  
      def testattributes(self):
          charge_Loewdin = [-1.25, 1.25]
          charge_Mulliken = [-1.30, 1.30]
          atomlist = ["O1", "Mn2"]
          types = ["O", "Mn"]
          num_atoms = 2
          self.assertArrayEqual(charge_Mulliken, self.charge2.Mulliken)
          self.assertArrayEqual(charge_Loewdin, self.charge2.Loewdin)
          self.assertArrayEqual(atomlist, self.charge2.atomlist)
          self.assertArrayEqual(types, self.charge2.types)
          self.assertArrayEqual(num_atoms, self.charge2.num_atoms)
  
      def test_get_structure_with_charges(self):
          structure_dict2 = {'lattice': {'c': 3.198244, 'volume': 23.132361565928807, 'b': 3.1982447183003364,
                                         'gamma': 60.00000011873414, 'beta': 60.00000401737447,
                                         'alpha': 60.00000742944491,
                                         'matrix': [[2.769761, 0.0, 1.599122], [0.923254, 2.611356, 1.599122],
                                                    [0.0, 0.0, 3.198244]], 'a': 3.1982443884113985},
                             '@class': 'Structure', 'sites': [{'xyz': [1.846502883732, 1.305680611356, 3.198248797366],
                                                               'properties': {'Loewdin Charges': -1.25,
                                                                              'Mulliken Charges': -1.3},
                                                               'abc': [0.499998, 0.500001, 0.500002],
                                                               'species': [{'occu': 1, 'element': 'O'}], 'label': 'O'},
                                                              {'xyz': [0.0, 0.0, 0.0],
                                                               'properties': {'Loewdin Charges': 1.25,
                                                                              'Mulliken Charges': 1.3},
                                                               'abc': [0.0, 0.0, 0.0],
                                                               'species': [{'occu': 1, 'element': 'Mn'}], 'label': 'Mn'}],
                             'charge': None, '@module': 'pymatgen.core.structure'}
          s2 = Structure.from_dict(structure_dict2)
          self.assertEqual(s2, self.charge2.get_structure_with_charges(os.path.join(this_dir, "../../tests/POSCAR.MnO")))
  
  
  class LobsteroutTest(PymatgenTest):
      def setUp(self):
          warnings.simplefilter("ignore")
          self.lobsterout_normal = Lobsterout(filename=os.path.join(test_dir, "lobsterout.normal"))
          # make sure .gz files are also read correctly
          self.lobsterout_normal = Lobsterout(filename=os.path.join(test_dir, "lobsterout.normal2.gz"))
          self.lobsterout_fatband_grosspop_densityofenergies = Lobsterout(
              filename=os.path.join(test_dir, "lobsterout.fatband_grosspop_densityofenergy"))
          self.lobsterout_saveprojection = Lobsterout(filename=os.path.join(test_dir, "lobsterout.saveprojection"))
          self.lobsterout_skipping_all = Lobsterout(filename=os.path.join(test_dir, "lobsterout.skipping_all"))
          self.lobsterout_twospins = Lobsterout(filename=os.path.join(test_dir, "lobsterout.twospins"))
          self.lobsterout_GaAs = Lobsterout(filename=os.path.join(test_dir, "lobsterout.GaAs"))
          self.lobsterout_from_projection = Lobsterout(filename=os.path.join(test_dir, "lobsterout_from_projection"))
          self.lobsterout_onethread = Lobsterout(filename=os.path.join(test_dir, "lobsterout.onethread"))
  
      def tearDown(self):
          warnings.simplefilter("default")
  
      def testattributes(self):
          self.assertListEqual(self.lobsterout_normal.basis_functions,
                               [['3s', '4s', '3p_y', '3p_z', '3p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_normal.basis_type, ['pbeVaspFit2015'])
          self.assertListEqual(self.lobsterout_normal.chargespilling, [0.0268])
          self.assertEqual(self.lobsterout_normal.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_normal.elements, ['Ti'])
          self.assertTrue(self.lobsterout_normal.has_CHARGE)
          self.assertTrue(self.lobsterout_normal.has_COHPCAR)
          self.assertTrue(self.lobsterout_normal.has_COOPCAR)
          self.assertTrue(self.lobsterout_normal.has_DOSCAR)
          self.assertFalse(self.lobsterout_normal.has_Projection)
          self.assertTrue(self.lobsterout_normal.has_bandoverlaps)
          self.assertFalse(self.lobsterout_normal.has_density_of_energies)
          self.assertFalse(self.lobsterout_normal.has_fatbands)
          self.assertFalse(self.lobsterout_normal.has_grosspopulation)
          self.assertListEqual(self.lobsterout_normal.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 21 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_normal.info_orthonormalization,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.'])
          self.assertFalse(self.lobsterout_normal.is_restart_from_projection)
          self.assertEqual(self.lobsterout_normal.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_normal.number_of_spins, 1)
          self.assertEqual(self.lobsterout_normal.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_normal.timing, {'walltime': {'h': '0', 'min': '0', 's': '2', 'ms': '702'},
                                                               'usertime': {'h': '0', 'min': '0', 's': '20', 'ms': '330'},
                                                               'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '310'}})
          self.assertAlmostEqual(self.lobsterout_normal.totalspilling[0], [0.044000000000000004][0])
          self.assertListEqual(self.lobsterout_normal.warninglines,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                'Generally, this is not a critical error. But to help you analyze it,',
                                'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                'Please check how much they deviate from the identity matrix and decide to',
                                'use your results only, if you are sure that this is ok.'])
  
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.basis_functions,
                               [['3s', '4s', '3p_y', '3p_z', '3p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.basis_type, ['pbeVaspFit2015'])
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.chargespilling, [0.0268])
          self.assertEqual(self.lobsterout_fatband_grosspop_densityofenergies.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.elements, ['Ti'])
          self.assertTrue(self.lobsterout_fatband_grosspop_densityofenergies.has_CHARGE)
          self.assertFalse(self.lobsterout_fatband_grosspop_densityofenergies.has_COHPCAR)
          self.assertFalse(self.lobsterout_fatband_grosspop_densityofenergies.has_COOPCAR)
          self.assertFalse(self.lobsterout_fatband_grosspop_densityofenergies.has_DOSCAR)
          self.assertFalse(self.lobsterout_fatband_grosspop_densityofenergies.has_Projection)
          self.assertTrue(self.lobsterout_fatband_grosspop_densityofenergies.has_bandoverlaps)
          self.assertTrue(self.lobsterout_fatband_grosspop_densityofenergies.has_density_of_energies)
          self.assertTrue(self.lobsterout_fatband_grosspop_densityofenergies.has_fatbands)
          self.assertTrue(self.lobsterout_fatband_grosspop_densityofenergies.has_grosspopulation)
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 21 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.info_orthonormalization,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.'])
          self.assertFalse(self.lobsterout_fatband_grosspop_densityofenergies.is_restart_from_projection)
          self.assertEqual(self.lobsterout_fatband_grosspop_densityofenergies.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_fatband_grosspop_densityofenergies.number_of_spins, 1)
          self.assertEqual(self.lobsterout_fatband_grosspop_densityofenergies.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_fatband_grosspop_densityofenergies.timing,
                               {'walltime': {'h': '0', 'min': '0', 's': '4', 'ms': '136'},
                                'usertime': {'h': '0', 'min': '0', 's': '18', 'ms': '280'},
                                'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '290'}})
          self.assertAlmostEqual(self.lobsterout_fatband_grosspop_densityofenergies.totalspilling[0],
                                 [0.044000000000000004][0])
          self.assertListEqual(self.lobsterout_fatband_grosspop_densityofenergies.warninglines,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                'Generally, this is not a critical error. But to help you analyze it,',
                                'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                'Please check how much they deviate from the identity matrix and decide to',
                                'use your results only, if you are sure that this is ok.'])
  
          self.assertListEqual(self.lobsterout_saveprojection.basis_functions,
                               [['3s', '4s', '3p_y', '3p_z', '3p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_saveprojection.basis_type, ['pbeVaspFit2015'])
          self.assertListEqual(self.lobsterout_saveprojection.chargespilling, [0.0268])
          self.assertEqual(self.lobsterout_saveprojection.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_saveprojection.elements, ['Ti'])
          self.assertTrue(self.lobsterout_saveprojection.has_CHARGE)
          self.assertFalse(self.lobsterout_saveprojection.has_COHPCAR)
          self.assertFalse(self.lobsterout_saveprojection.has_COOPCAR)
          self.assertFalse(self.lobsterout_saveprojection.has_DOSCAR)
          self.assertTrue(self.lobsterout_saveprojection.has_Projection)
          self.assertTrue(self.lobsterout_saveprojection.has_bandoverlaps)
          self.assertTrue(self.lobsterout_saveprojection.has_density_of_energies)
          self.assertFalse(self.lobsterout_saveprojection.has_fatbands)
          self.assertFalse(self.lobsterout_saveprojection.has_grosspopulation)
          self.assertListEqual(self.lobsterout_saveprojection.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 21 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_saveprojection.info_orthonormalization,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.'])
          self.assertFalse(self.lobsterout_saveprojection.is_restart_from_projection)
          self.assertEqual(self.lobsterout_saveprojection.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_saveprojection.number_of_spins, 1)
          self.assertEqual(self.lobsterout_saveprojection.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_saveprojection.timing,
                               {'walltime': {'h': '0', 'min': '0', 's': '2', 'ms': '574'},
                                'usertime': {'h': '0', 'min': '0', 's': '18', 'ms': '250'},
                                'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '320'}})
          self.assertAlmostEqual(self.lobsterout_saveprojection.totalspilling[0], [0.044000000000000004][0])
          self.assertListEqual(self.lobsterout_saveprojection.warninglines,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                'Generally, this is not a critical error. But to help you analyze it,',
                                'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                'Please check how much they deviate from the identity matrix and decide to',
                                'use your results only, if you are sure that this is ok.'])
  
          self.assertListEqual(self.lobsterout_skipping_all.basis_functions,
                               [['3s', '4s', '3p_y', '3p_z', '3p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_skipping_all.basis_type, ['pbeVaspFit2015'])
          self.assertListEqual(self.lobsterout_skipping_all.chargespilling, [0.0268])
          self.assertEqual(self.lobsterout_skipping_all.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_skipping_all.elements, ['Ti'])
          self.assertFalse(self.lobsterout_skipping_all.has_CHARGE)
          self.assertFalse(self.lobsterout_skipping_all.has_COHPCAR)
          self.assertFalse(self.lobsterout_skipping_all.has_COOPCAR)
          self.assertFalse(self.lobsterout_skipping_all.has_DOSCAR)
          self.assertFalse(self.lobsterout_skipping_all.has_Projection)
          self.assertTrue(self.lobsterout_skipping_all.has_bandoverlaps)
          self.assertFalse(self.lobsterout_skipping_all.has_density_of_energies)
          self.assertFalse(self.lobsterout_skipping_all.has_fatbands)
          self.assertFalse(self.lobsterout_skipping_all.has_grosspopulation)
          self.assertListEqual(self.lobsterout_skipping_all.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 21 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_skipping_all.info_orthonormalization,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.'])
          self.assertFalse(self.lobsterout_skipping_all.is_restart_from_projection)
          self.assertEqual(self.lobsterout_skipping_all.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_skipping_all.number_of_spins, 1)
          self.assertEqual(self.lobsterout_skipping_all.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_skipping_all.timing,
                               {'walltime': {'h': '0', 'min': '0', 's': '2', 'ms': '117'},
                                'usertime': {'h': '0', 'min': '0', 's': '16', 'ms': '79'},
                                'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '320'}})
          self.assertAlmostEqual(self.lobsterout_skipping_all.totalspilling[0], [0.044000000000000004][0])
          self.assertListEqual(self.lobsterout_skipping_all.warninglines,
                               ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                'Generally, this is not a critical error. But to help you analyze it,',
                                'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                'Please check how much they deviate from the identity matrix and decide to',
                                'use your results only, if you are sure that this is ok.'])
  
          self.assertListEqual(self.lobsterout_twospins.basis_functions,
                               [['4s', '4p_y', '4p_z', '4p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_twospins.basis_type, ['pbeVaspFit2015'])
          self.assertAlmostEqual(self.lobsterout_twospins.chargespilling[0], 0.36619999999999997)
          self.assertAlmostEqual(self.lobsterout_twospins.chargespilling[1], 0.36619999999999997)
          self.assertEqual(self.lobsterout_twospins.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_twospins.elements, ['Ti'])
          self.assertTrue(self.lobsterout_twospins.has_CHARGE)
          self.assertTrue(self.lobsterout_twospins.has_COHPCAR)
          self.assertTrue(self.lobsterout_twospins.has_COOPCAR)
          self.assertTrue(self.lobsterout_twospins.has_DOSCAR)
          self.assertFalse(self.lobsterout_twospins.has_Projection)
          self.assertTrue(self.lobsterout_twospins.has_bandoverlaps)
          self.assertFalse(self.lobsterout_twospins.has_density_of_energies)
          self.assertFalse(self.lobsterout_twospins.has_fatbands)
          self.assertFalse(self.lobsterout_twospins.has_grosspopulation)
          self.assertListEqual(self.lobsterout_twospins.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 19 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_twospins.info_orthonormalization,
                               ['60 of 294 k-points could not be orthonormalized with an accuracy of 1.0E-5.'])
          self.assertFalse(self.lobsterout_twospins.is_restart_from_projection)
          self.assertEqual(self.lobsterout_twospins.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_twospins.number_of_spins, 2)
          self.assertEqual(self.lobsterout_twospins.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_twospins.timing, {'walltime': {'h': '0', 'min': '0', 's': '3', 'ms': '71'},
                                                                 'usertime': {'h': '0', 'min': '0', 's': '22',
                                                                              'ms': '660'},
                                                                 'sys_time': {'h': '0', 'min': '0', 's': '0',
                                                                              'ms': '310'}})
          self.assertAlmostEqual(self.lobsterout_twospins.totalspilling[0], [0.2567][0])
          self.assertAlmostEqual(self.lobsterout_twospins.totalspilling[1], [0.2567][0])
          self.assertListEqual(self.lobsterout_twospins.warninglines,
                               ['60 of 294 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                'Generally, this is not a critical error. But to help you analyze it,',
                                'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                'Please check how much they deviate from the identity matrix and decide to',
                                'use your results only, if you are sure that this is ok.'])
  
          self.assertListEqual(self.lobsterout_from_projection.basis_functions,
                               [])
          self.assertListEqual(self.lobsterout_from_projection.basis_type, [])
          self.assertAlmostEqual(self.lobsterout_from_projection.chargespilling[0], 0.0177)
          self.assertEqual(self.lobsterout_from_projection.dftprogram, None)
          self.assertListEqual(self.lobsterout_from_projection.elements, [])
          self.assertTrue(self.lobsterout_from_projection.has_CHARGE)
          self.assertTrue(self.lobsterout_from_projection.has_COHPCAR)
          self.assertTrue(self.lobsterout_from_projection.has_COOPCAR)
          self.assertTrue(self.lobsterout_from_projection.has_DOSCAR)
          self.assertFalse(self.lobsterout_from_projection.has_Projection)
          self.assertFalse(self.lobsterout_from_projection.has_bandoverlaps)
          self.assertFalse(self.lobsterout_from_projection.has_density_of_energies)
          self.assertFalse(self.lobsterout_from_projection.has_fatbands)
          self.assertFalse(self.lobsterout_from_projection.has_grosspopulation)
          self.assertListEqual(self.lobsterout_from_projection.info_lines,
                               [])
          self.assertListEqual(self.lobsterout_from_projection.info_orthonormalization,
                               [])
          self.assertTrue(self.lobsterout_from_projection.is_restart_from_projection)
          self.assertEqual(self.lobsterout_from_projection.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_from_projection.number_of_spins, 1)
          self.assertEqual(self.lobsterout_from_projection.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_from_projection.timing,
                               {'walltime': {'h': '0', 'min': '2', 's': '1', 'ms': '890'},
                                'usertime': {'h': '0', 'min': '15', 's': '10', 'ms': '530'},
                                'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '400'}})
          self.assertAlmostEqual(self.lobsterout_from_projection.totalspilling[0], [0.1543][0])
          self.assertListEqual(self.lobsterout_from_projection.warninglines,
                               [])
  
          self.assertListEqual(self.lobsterout_GaAs.basis_functions,
                               [['4s', '4p_y', '4p_z', '4p_x'],
                                ['4s', '4p_y', '4p_z', '4p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']])
          self.assertListEqual(self.lobsterout_GaAs.basis_type, ['Bunge', 'Bunge'])
          self.assertAlmostEqual(self.lobsterout_GaAs.chargespilling[0], 0.0089)
          self.assertEqual(self.lobsterout_GaAs.dftprogram, 'VASP')
          self.assertListEqual(self.lobsterout_GaAs.elements, ['As', 'Ga'])
          self.assertTrue(self.lobsterout_GaAs.has_CHARGE)
          self.assertTrue(self.lobsterout_GaAs.has_COHPCAR)
          self.assertTrue(self.lobsterout_GaAs.has_COOPCAR)
          self.assertTrue(self.lobsterout_GaAs.has_DOSCAR)
          self.assertFalse(self.lobsterout_GaAs.has_Projection)
          self.assertFalse(self.lobsterout_GaAs.has_bandoverlaps)
          self.assertFalse(self.lobsterout_GaAs.has_density_of_energies)
          self.assertFalse(self.lobsterout_GaAs.has_fatbands)
          self.assertFalse(self.lobsterout_GaAs.has_grosspopulation)
          self.assertListEqual(self.lobsterout_GaAs.info_lines,
                               ['There are more PAW bands than local basis functions available.',
                                'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                'the PAW bands from 14 and upwards will be ignored.'])
          self.assertListEqual(self.lobsterout_GaAs.info_orthonormalization,
                               [])
          self.assertFalse(self.lobsterout_GaAs.is_restart_from_projection)
          self.assertEqual(self.lobsterout_GaAs.lobster_version, 'v3.1.0')
          self.assertEqual(self.lobsterout_GaAs.number_of_spins, 1)
          self.assertEqual(self.lobsterout_GaAs.number_of_threads, 8)
          self.assertDictEqual(self.lobsterout_GaAs.timing, {'walltime': {'h': '0', 'min': '0', 's': '2', 'ms': '726'},
                                                             'usertime': {'h': '0', 'min': '0', 's': '12', 'ms': '370'},
                                                             'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '180'}})
          self.assertAlmostEqual(self.lobsterout_GaAs.totalspilling[0], [0.0859][0])
  
          self.assertEqual(self.lobsterout_onethread.number_of_threads, 1)
  
      def test_get_doc(self):
          comparedict = {'restart_from_projection': False, 'lobster_version': 'v3.1.0', 'threads': 8,
                         'Dftprogram': 'VASP', 'chargespilling': [0.0268], 'totalspilling': [0.044000000000000004],
                         'elements': ['Ti'], 'basistype': ['pbeVaspFit2015'],
                         'basisfunctions': [[
                             '3s', '4s', '3p_y', '3p_z', '3p_x', '3d_xy', '3d_yz', '3d_z^2', '3d_xz', '3d_x^2-y^2']],
                         'timing': {'walltime': {'h': '0', 'min': '0', 's': '2', 'ms': '702'},
                                    'usertime': {'h': '0', 'min': '0', 's': '20', 'ms': '330'},
                                    'sys_time': {'h': '0', 'min': '0', 's': '0', 'ms': '310'}},
                         'warnings': ['3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.',
                                      'Generally, this is not a critical error. But to help you analyze it,',
                                      'I dumped the band overlap matrices to the file bandOverlaps.lobster.',
                                      'Please check how much they deviate from the identity matrix and decide to',
                                      'use your results only, if you are sure that this is ok.'],
                         'orthonormalization': [
                             '3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.'],
                         'infos': ['There are more PAW bands than local basis functions available.',
                                   'To prevent trouble in orthonormalization and Hamiltonian reconstruction',
                                   'the PAW bands from 21 and upwards will be ignored.'], 'hasDOSCAR': True,
                         'hasCOHPCAR': True, 'hasCOOPCAR': True, 'hasCHARGE': True, 'hasProjection': False,
                         'hasbandoverlaps': True, 'hasfatband': False, 'hasGrossPopuliation': False,
                         'hasDensityOfEnergies': False}
          for key, item in self.lobsterout_normal.get_doc().items():
              if isinstance(item, str):
                  self.assertTrue(comparedict[key], item)
              elif isinstance(item, int):
                  self.assertEqual(comparedict[key], item)
              elif key in ('chargespilling', 'totalspilling'):
                  self.assertAlmostEqual(item[0], comparedict[key][0])
              elif isinstance(item, list):
                  self.assertListEqual(item, comparedict[key])
              elif isinstance(item, dict):
                  self.assertDictEqual(item, comparedict[key])
  
  
  class FatbandTest(PymatgenTest):
      def setUp(self):
          warnings.simplefilter("ignore")
          self.fatband_SiO2_p_x = Fatband(filenames=os.path.join(test_dir, "Fatband_SiO2/Test_p_x"),
                                          Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/KPOINTS"),
                                          vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/vasprun.xml"))
          self.vasprun_SiO2_p_x = Vasprun(filename=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/vasprun.xml"))
          self.bs_symmline = self.vasprun_SiO2_p_x.get_band_structure(line_mode=True, force_hybrid_mode=True)
          self.fatband_SiO2_p = Fatband(filenames=os.path.join(test_dir, "Fatband_SiO2/Test_p"),
                                        Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_p/KPOINTS"),
                                        vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_p/vasprun.xml"))
          self.vasprun_SiO2_p = Vasprun(filename=os.path.join(test_dir, "Fatband_SiO2/Test_p/vasprun.xml"))
          self.bs_symmline2 = self.vasprun_SiO2_p.get_band_structure(line_mode=True, force_hybrid_mode=True)
          self.fatband_SiO2_spin = Fatband(filenames=os.path.join(test_dir, "Fatband_SiO2/Test_Spin"),
                                           Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_Spin/KPOINTS"),
                                           vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_Spin/vasprun.xml"))
          self.vasprun_SiO2_spin = Vasprun(filename=os.path.join(test_dir, "Fatband_SiO2/Test_Spin/vasprun.xml"))
          self.bs_symmline_spin = self.vasprun_SiO2_p.get_band_structure(line_mode=True, force_hybrid_mode=True)
  
      def tearDown(self):
          warnings.simplefilter("default")
  
      def test_attributes(self):
          self.assertAlmostEqual(list(self.fatband_SiO2_p_x.label_dict['M'])[0], 0.5)
          self.assertAlmostEqual(list(self.fatband_SiO2_p_x.label_dict['M'])[1], 0.0)
          self.assertAlmostEqual(list(self.fatband_SiO2_p_x.label_dict['M'])[2], 0.0)
          self.assertEqual(self.fatband_SiO2_p_x.efermi, self.vasprun_SiO2_p_x.efermi)
          lattice1 = self.bs_symmline.lattice_rec.as_dict()
          lattice2 = self.fatband_SiO2_p_x.lattice.as_dict()
          self.assertAlmostEqual(lattice1["matrix"][0][0], lattice2["matrix"][0][0])
          self.assertAlmostEqual(lattice1["matrix"][0][1], lattice2["matrix"][0][1])
          self.assertAlmostEqual(lattice1["matrix"][0][2], lattice2["matrix"][0][2])
          self.assertAlmostEqual(lattice1["matrix"][1][0], lattice2["matrix"][1][0])
          self.assertAlmostEqual(lattice1["matrix"][1][1], lattice2["matrix"][1][1])
          self.assertAlmostEqual(lattice1["matrix"][1][2], lattice2["matrix"][1][2])
          self.assertAlmostEqual(lattice1["matrix"][2][0], lattice2["matrix"][2][0])
          self.assertAlmostEqual(lattice1["matrix"][2][1], lattice2["matrix"][2][1])
          self.assertAlmostEqual(lattice1["matrix"][2][2], lattice2["matrix"][2][2])
          self.assertEqual(self.fatband_SiO2_p_x.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p_x.efermi, -18.245)
          self.assertEqual(self.fatband_SiO2_p_x.is_spinpolarized, False)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.kpoints_array[3][0], 0.03409091)
          self.assertEqual(self.fatband_SiO2_p_x.kpoints_array[3][1], 0.0)
          self.assertEqual(self.fatband_SiO2_p_x.kpoints_array[3][2], 0.0)
          self.assertEqual(self.fatband_SiO2_p_x.nbands, 36)
          self.assertEqual(self.fatband_SiO2_p_x.p_eigenvals[Spin.up][2][1]["Si1"]["3p_x"], 0.002)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].frac_coords[0], 0.)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].frac_coords[1], 0.47634315)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].frac_coords[2], 0.666667)
          self.assertEqual(self.fatband_SiO2_p_x.structure[0].species_string, 'Si')
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].coords[0], -1.19607309)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].coords[1], 2.0716597)
          self.assertAlmostEqual(self.fatband_SiO2_p_x.structure[0].coords[2], 3.67462144)
  
          self.assertAlmostEqual(list(self.fatband_SiO2_p.label_dict['M'])[0], 0.5)
          self.assertAlmostEqual(list(self.fatband_SiO2_p.label_dict['M'])[1], 0.0)
          self.assertAlmostEqual(list(self.fatband_SiO2_p.label_dict['M'])[2], 0.0)
          self.assertEqual(self.fatband_SiO2_p.efermi, self.vasprun_SiO2_p.efermi)
          lattice1 = self.bs_symmline2.lattice_rec.as_dict()
          lattice2 = self.fatband_SiO2_p.lattice.as_dict()
          self.assertAlmostEqual(lattice1["matrix"][0][0], lattice2["matrix"][0][0])
          self.assertAlmostEqual(lattice1["matrix"][0][1], lattice2["matrix"][0][1])
          self.assertAlmostEqual(lattice1["matrix"][0][2], lattice2["matrix"][0][2])
          self.assertAlmostEqual(lattice1["matrix"][1][0], lattice2["matrix"][1][0])
          self.assertAlmostEqual(lattice1["matrix"][1][1], lattice2["matrix"][1][1])
          self.assertAlmostEqual(lattice1["matrix"][1][2], lattice2["matrix"][1][2])
          self.assertAlmostEqual(lattice1["matrix"][2][0], lattice2["matrix"][2][0])
          self.assertAlmostEqual(lattice1["matrix"][2][1], lattice2["matrix"][2][1])
          self.assertAlmostEqual(lattice1["matrix"][2][2], lattice2["matrix"][2][2])
          self.assertEqual(self.fatband_SiO2_p.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p.efermi, -18.245)
          self.assertEqual(self.fatband_SiO2_p.is_spinpolarized, False)
          self.assertAlmostEqual(self.fatband_SiO2_p.kpoints_array[3][0], 0.03409091)
          self.assertEqual(self.fatband_SiO2_p.kpoints_array[3][1], 0.0)
          self.assertEqual(self.fatband_SiO2_p.kpoints_array[3][2], 0.0)
          self.assertEqual(self.fatband_SiO2_p.nbands, 36)
          self.assertEqual(self.fatband_SiO2_p.p_eigenvals[Spin.up][2][1]["Si1"]["3p"], 0.042)
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].frac_coords[0], 0.)
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].frac_coords[1], 0.47634315)
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].frac_coords[2], 0.666667)
          self.assertEqual(self.fatband_SiO2_p.structure[0].species_string, 'Si')
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].coords[0], -1.19607309)
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].coords[1], 2.0716597)
          self.assertAlmostEqual(self.fatband_SiO2_p.structure[0].coords[2], 3.67462144)
  
          self.assertAlmostEqual(list(self.fatband_SiO2_spin.label_dict['M'])[0], 0.5)
          self.assertAlmostEqual(list(self.fatband_SiO2_spin.label_dict['M'])[1], 0.)
          self.assertAlmostEqual(list(self.fatband_SiO2_spin.label_dict['M'])[2], 0.)
          self.assertEqual(self.fatband_SiO2_spin.efermi, self.vasprun_SiO2_spin.efermi)
          lattice1 = self.bs_symmline_spin.lattice_rec.as_dict()
          lattice2 = self.fatband_SiO2_spin.lattice.as_dict()
          self.assertAlmostEqual(lattice1["matrix"][0][0], lattice2["matrix"][0][0])
          self.assertAlmostEqual(lattice1["matrix"][0][1], lattice2["matrix"][0][1])
          self.assertAlmostEqual(lattice1["matrix"][0][2], lattice2["matrix"][0][2])
          self.assertAlmostEqual(lattice1["matrix"][1][0], lattice2["matrix"][1][0])
          self.assertAlmostEqual(lattice1["matrix"][1][1], lattice2["matrix"][1][1])
          self.assertAlmostEqual(lattice1["matrix"][1][2], lattice2["matrix"][1][2])
          self.assertAlmostEqual(lattice1["matrix"][2][0], lattice2["matrix"][2][0])
          self.assertAlmostEqual(lattice1["matrix"][2][1], lattice2["matrix"][2][1])
          self.assertAlmostEqual(lattice1["matrix"][2][2], lattice2["matrix"][2][2])
          self.assertEqual(self.fatband_SiO2_spin.eigenvals[Spin.up][1][1] - self.fatband_SiO2_spin.efermi, -18.245)
          self.assertEqual(self.fatband_SiO2_spin.eigenvals[Spin.down][1][1] - self.fatband_SiO2_spin.efermi, -18.245)
          self.assertEqual(self.fatband_SiO2_spin.is_spinpolarized, True)
          self.assertAlmostEqual(self.fatband_SiO2_spin.kpoints_array[3][0], 0.03409091)
          self.assertEqual(self.fatband_SiO2_spin.kpoints_array[3][1], 0.0)
          self.assertEqual(self.fatband_SiO2_spin.kpoints_array[3][2], 0.0)
          self.assertEqual(self.fatband_SiO2_spin.nbands, 36)
  
          self.assertEqual(self.fatband_SiO2_spin.p_eigenvals[Spin.up][2][1]["Si1"]["3p"], 0.042)
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].frac_coords[0], 0.)
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].frac_coords[1], 0.47634315)
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].frac_coords[2], 0.666667)
          self.assertEqual(self.fatband_SiO2_spin.structure[0].species_string, 'Si')
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].coords[0], -1.19607309)
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].coords[1], 2.0716597)
          self.assertAlmostEqual(self.fatband_SiO2_spin.structure[0].coords[2], 3.67462144)
  
      def test_raises(self):
          with self.assertRaises(ValueError):
              self.fatband_SiO2_p_x = Fatband(
                  filenames=[os.path.join(test_dir, "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster"),
                             os.path.join(test_dir, "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster")],
                  Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/KPOINTS"),
                  vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/vasprun.xml"))
  
          with self.assertRaises(ValueError):
              self.fatband_SiO2_p_x = Fatband(
                  filenames=[os.path.join(test_dir, "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster"),
                             os.path.join(test_dir, "Fatband_SiO2/Test_p/FATBAND_si1_3p.lobster")],
                  Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/KPOINTS"),
                  vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/vasprun.xml"))
  
          with self.assertRaises(ValueError):
              self.fatband_SiO2_p_x = Fatband(filenames='.',
                                              Kpointsfile=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/KPOINTS"),
                                              vasprun=os.path.join(test_dir, "Fatband_SiO2/Test_p_x/vasprun.xml"))
  
      def test_get_bandstructure(self):
          bs_p = self.fatband_SiO2_p.get_bandstructure()
          atom1 = bs_p.structure[0]
          atom2 = self.bs_symmline2.structure[0]
          self.assertAlmostEqual(atom1.frac_coords[0], atom2.frac_coords[0])
          self.assertAlmostEqual(atom1.frac_coords[1], atom2.frac_coords[1])
          self.assertAlmostEqual(atom1.frac_coords[2], atom2.frac_coords[2])
          self.assertAlmostEqual(atom1.coords[0], atom2.coords[0])
          self.assertAlmostEqual(atom1.coords[1], atom2.coords[1])
          self.assertAlmostEqual(atom1.coords[2], atom2.coords[2])
          self.assertEqual(atom1.species_string, atom2.species_string)
          self.assertEqual(bs_p.efermi, self.bs_symmline2.efermi)
          branch1 = bs_p.branches[0]
          branch2 = self.bs_symmline2.branches[0]
          self.assertEqual(branch2["name"], branch1["name"])
          self.assertEqual(branch2["start_index"], branch1["start_index"])
          self.assertEqual(branch2["end_index"], branch1["end_index"])
  
          self.assertAlmostEqual(bs_p.distance[30], self.bs_symmline2.distance[30])
          lattice1 = bs_p.lattice_rec.as_dict()
          lattice2 = self.bs_symmline2.lattice_rec.as_dict()
          self.assertAlmostEqual(lattice1["matrix"][0][0], lattice2["matrix"][0][0])
          self.assertAlmostEqual(lattice1["matrix"][0][1], lattice2["matrix"][0][1])
          self.assertAlmostEqual(lattice1["matrix"][0][2], lattice2["matrix"][0][2])
          self.assertAlmostEqual(lattice1["matrix"][1][0], lattice2["matrix"][1][0])
          self.assertAlmostEqual(lattice1["matrix"][1][1], lattice2["matrix"][1][1])
          self.assertAlmostEqual(lattice1["matrix"][1][2], lattice2["matrix"][1][2])
          self.assertAlmostEqual(lattice1["matrix"][2][0], lattice2["matrix"][2][0])
          self.assertAlmostEqual(lattice1["matrix"][2][1], lattice2["matrix"][2][1])
          self.assertAlmostEqual(lattice1["matrix"][2][2], lattice2["matrix"][2][2])
  
          self.assertAlmostEqual(bs_p.kpoints[8].frac_coords[0], self.bs_symmline2.kpoints[8].frac_coords[0])
          self.assertAlmostEqual(bs_p.kpoints[8].frac_coords[1], self.bs_symmline2.kpoints[8].frac_coords[1])
          self.assertAlmostEqual(bs_p.kpoints[8].frac_coords[2], self.bs_symmline2.kpoints[8].frac_coords[2])
          self.assertAlmostEqual(bs_p.kpoints[8].cart_coords[0], self.bs_symmline2.kpoints[8].cart_coords[0])
          self.assertAlmostEqual(bs_p.kpoints[8].cart_coords[1], self.bs_symmline2.kpoints[8].cart_coords[1])
          self.assertAlmostEqual(bs_p.kpoints[8].cart_coords[2], self.bs_symmline2.kpoints[8].cart_coords[2])
          self.assertAlmostEqual(bs_p.kpoints[50].frac_coords[0], self.bs_symmline2.kpoints[50].frac_coords[0])
          self.assertAlmostEqual(bs_p.kpoints[50].frac_coords[1], self.bs_symmline2.kpoints[50].frac_coords[1])
          self.assertAlmostEqual(bs_p.kpoints[50].frac_coords[2], self.bs_symmline2.kpoints[50].frac_coords[2])
          self.assertAlmostEqual(bs_p.kpoints[50].cart_coords[0], self.bs_symmline2.kpoints[50].cart_coords[0])
          self.assertAlmostEqual(bs_p.kpoints[50].cart_coords[1], self.bs_symmline2.kpoints[50].cart_coords[1])
          self.assertAlmostEqual(bs_p.kpoints[50].cart_coords[2], self.bs_symmline2.kpoints[50].cart_coords[2])
          self.assertAlmostEqual(bs_p.get_band_gap()["energy"], self.bs_symmline2.get_band_gap()["energy"], places=2)
          self.assertAlmostEqual(bs_p.get_projection_on_elements()[Spin.up][0][0]["Si"], 3 * (0.001 + 0.064))
          self.assertAlmostEqual(
              bs_p.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.up][0][0]["Si"]["3p"],
              0.003)
          self.assertAlmostEqual(
              bs_p.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.up][0][0]["O"]["2p"],
              0.002 * 3 + 0.003 * 3)
          dict_here = bs_p.get_projections_on_elements_and_orbitals({
              "Si": ["3s", "3p"], "O": ["2s", "2p"]})[Spin.up][0][0]
          self.assertAlmostEqual(dict_here["Si"]["3s"], 0.192)
          self.assertAlmostEqual(dict_here["Si"]["3p"], 0.003)
          self.assertAlmostEqual(dict_here["O"]["2s"], 0.792)
          self.assertAlmostEqual(dict_here["O"]["2p"], 0.015)
  
          bs_spin = self.fatband_SiO2_spin.get_bandstructure()
          self.assertAlmostEqual(bs_spin.get_projection_on_elements()[Spin.up][0][0]["Si"], 3 * (0.001 + 0.064))
          self.assertAlmostEqual(
              bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.up][0][0]["Si"]["3p"],
              0.003)
          self.assertAlmostEqual(
              bs_spin.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.up][0][0]["O"]["2p"],
              0.002 * 3 + 0.003 * 3)
          dict_here = \
              bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3s", "3p"], "O": ["2s", "2p"]})[Spin.up][0][0]
          self.assertAlmostEqual(dict_here["Si"]["3s"], 0.192)
          self.assertAlmostEqual(dict_here["Si"]["3p"], 0.003)
          self.assertAlmostEqual(dict_here["O"]["2s"], 0.792)
          self.assertAlmostEqual(dict_here["O"]["2p"], 0.015)
  
          self.assertAlmostEqual(bs_spin.get_projection_on_elements()[Spin.up][0][0]["Si"], 3 * (0.001 + 0.064))
          self.assertAlmostEqual(
              bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.down][0][0]["Si"]["3p"],
              0.003)
          self.assertAlmostEqual(
              bs_spin.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.down][0][0]["O"]["2p"],
              0.002 * 3 + 0.003 * 3)
          dict_here = \
              bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3s", "3p"], "O": ["2s", "2p"]})[Spin.down][0][
                  0]
          self.assertAlmostEqual(dict_here["Si"]["3s"], 0.192)
          self.assertAlmostEqual(dict_here["Si"]["3p"], 0.003)
          self.assertAlmostEqual(dict_here["O"]["2s"], 0.792)
          self.assertAlmostEqual(dict_here["O"]["2p"], 0.015)
          bs_p_x = self.fatband_SiO2_p_x.get_bandstructure()
          self.assertAlmostEqual(bs_p_x.get_projection_on_elements()[Spin.up][0][0]["Si"], 3 * (0.001 + 0.064), 2)
  
  
  class LobsterinTest(unittest.TestCase):
      def setUp(self):
          warnings.simplefilter("ignore")
          self.Lobsterinfromfile = Lobsterin.from_file(os.path.join(test_dir, "lobsterin.1"))
          self.Lobsterinfromfile2 = Lobsterin.from_file(os.path.join(test_dir, "lobsterin.2"))
          self.Lobsterinfromfile3 = Lobsterin.from_file(os.path.join(test_dir, "lobsterin.3"))
          self.Lobsterinfromfile4 = Lobsterin.from_file(os.path.join(test_dir, "lobsterin.4.gz"))
  
      def test_from_file(self):
          # test read from file
          self.assertAlmostEqual(self.Lobsterinfromfile["cohpstartenergy"], -15.0)
          self.assertAlmostEqual(self.Lobsterinfromfile["cohpendenergy"], 5.0)
          self.assertAlmostEqual(self.Lobsterinfromfile["basisset"], 'pbeVaspFit2015')
          self.assertAlmostEqual(self.Lobsterinfromfile["gaussiansmearingwidth"], 0.1)
          self.assertEqual(self.Lobsterinfromfile["basisfunctions"][0], 'Fe 3d 4p 4s')
          self.assertEqual(self.Lobsterinfromfile["basisfunctions"][1], 'Co 3d 4p 4s')
          self.assertEqual(self.Lobsterinfromfile["skipdos"], True)
          self.assertEqual(self.Lobsterinfromfile["skipcohp"], True)
          self.assertEqual(self.Lobsterinfromfile["skipcoop"], True)
          self.assertEqual(self.Lobsterinfromfile["skippopulationanalysis"], True)
          self.assertEqual(self.Lobsterinfromfile["skipgrosspopulation"], True)
  
          # test if comments are correctly removed
          self.assertDictEqual(self.Lobsterinfromfile, self.Lobsterinfromfile2)
  
      def test_getitem(self):
          # tests implementation of getitem, should be case independent
          self.assertAlmostEqual(self.Lobsterinfromfile["COHPSTARTENERGY"], -15.0)
  
      def test_setitem(self):
          # test implementation of setitem
          self.Lobsterinfromfile["skipCOHP"] = False
          self.assertEqual(self.Lobsterinfromfile["skipcohp"], False)
  
      def test_initialize_from_dict(self):
          # initialize from dict
          lobsterin1 = Lobsterin(
              {'cohpstartenergy': -15.0, 'cohpendenergy': 5.0, 'basisset': 'pbeVaspFit2015', 'gaussiansmearingwidth': 0.1,
               'basisfunctions': ['Fe 3d 4p 4s', 'Co 3d 4p 4s'], 'skipdos': True, 'skipcohp': True, 'skipcoop': True,
               'skippopulationanalysis': True, 'skipgrosspopulation': True})
          self.assertAlmostEqual(lobsterin1["cohpstartenergy"], -15.0)
          self.assertAlmostEqual(lobsterin1["cohpendenergy"], 5.0)
          self.assertAlmostEqual(lobsterin1["basisset"], 'pbeVaspFit2015')
          self.assertAlmostEqual(lobsterin1["gaussiansmearingwidth"], 0.1)
          self.assertEqual(lobsterin1["basisfunctions"][0], 'Fe 3d 4p 4s')
          self.assertEqual(lobsterin1["basisfunctions"][1], 'Co 3d 4p 4s')
          self.assertEqual(lobsterin1["skipdos"], True)
          self.assertEqual(lobsterin1["skipcohp"], True)
          self.assertEqual(lobsterin1["skipcoop"], True)
          self.assertEqual(lobsterin1["skippopulationanalysis"], True)
          self.assertEqual(lobsterin1["skipgrosspopulation"], True)
          with self.assertRaises(IOError):
              lobsterin2 = Lobsterin({'cohpstartenergy': -15.0, 'cohpstartEnergy': -20.0})
          lobsterin2 = Lobsterin({'cohpstartenergy': -15.0})
          # can only calculate nbands if basis functions are provided
          with self.assertRaises(IOError):
              lobsterin2._get_nbands(structure=Structure.from_file(os.path.join(test_dir_doscar, "POSCAR.Fe3O4")))
  
      def test_standard_settings(self):
          # test standard settings
          for option in ['standard', 'standard_from_projection', 'standard_with_fatband', 'onlyprojection', 'onlydos',
                         'onlycohp', 'onlycoop', 'onlycohpcoop']:
  
              lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                                           os.path.join(test_dir_doscar, "INCAR.lobster"),
                                                                           os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
                                                                           option=option)
              self.assertAlmostEqual(lobsterin1["cohpstartenergy"], -15.0)
              self.assertAlmostEqual(lobsterin1["cohpendenergy"], 5.0)
              self.assertAlmostEqual(lobsterin1["basisset"], 'pbeVaspFit2015')
              self.assertAlmostEqual(lobsterin1["gaussiansmearingwidth"], 0.1)
              self.assertEqual(lobsterin1["basisfunctions"][0], 'Fe 3d 4p 4s ')
              self.assertEqual(lobsterin1["basisfunctions"][1], 'O 2p 2s ')
  
              if option in ['standard', 'standard_with_fatband', 'onlyprojection', 'onlycohp', 'onlycoop',
                            'onlycohpcoop']:
                  self.assertEqual(lobsterin1["saveProjectiontoFile"], True)
              if option in ['standard', 'standard_with_fatband', 'onlycohp', 'onlycoop',
                            'onlycohpcoop']:
                  self.assertEqual(lobsterin1["cohpGenerator"], 'from 0.1 to 6.0 orbitalwise')
              if option in ['standard']:
                  self.assertEqual('skipdos' not in lobsterin1, True)
                  self.assertEqual('skipcohp' not in lobsterin1, True)
                  self.assertEqual('skipcoop' not in lobsterin1, True)
              if option in ['standard_with_fatband']:
                  self.assertListEqual(lobsterin1["createFatband"], ['Fe 3d 4p 4s ', 'O 2p 2s '])
                  self.assertEqual('skipdos' not in lobsterin1, True)
                  self.assertEqual('skipcohp' not in lobsterin1, True)
                  self.assertEqual('skipcoop' not in lobsterin1, True)
              if option in ['standard_from_projection']:
                  self.assertTrue(lobsterin1['loadProjectionFromFile'], True)
              if option in ['onlyprojection', 'onlycohp', 'onlycoop', 'onlycohpcoop']:
                  self.assertTrue(lobsterin1['skipdos'], True)
                  self.assertTrue(lobsterin1['skipPopulationAnalysis'], True)
                  self.assertTrue(lobsterin1['skipGrossPopulation'], True)
              if option in ['onlydos']:
                  self.assertTrue(lobsterin1['skipPopulationAnalysis'], True)
                  self.assertTrue(lobsterin1['skipGrossPopulation'], True)
                  self.assertTrue(lobsterin1['skipcohp'], True)
                  self.assertTrue(lobsterin1['skipcoop'], True)
              if option in ['onlycohp']:
                  self.assertTrue(lobsterin1['skipcoop'], True)
              if option in ['onlycoop']:
                  self.assertTrue(lobsterin1['skipcohp'], True)
              if option in ['onlyprojection']:
                  self.assertTrue(lobsterin1['skipdos'], True)
  
          # test basis functions by dict
          lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                                          os.path.join(test_dir_doscar, "INCAR.lobster"),
                                                                          dict_for_basis={"Fe": '3d 4p 4s', "O": '2s 2p'},
                                                                          option='standard')
          self.assertListEqual(lobsterin_new['basisfunctions'], ['Fe 3d 4p 4s', 'O 2s 2p'])
  
          # test gaussian smearing
          lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                                          os.path.join(test_dir_doscar, "INCAR.lobster2"),
                                                                          dict_for_basis={"Fe": '3d 4p 4s', "O": '2s 2p'},
                                                                          option='standard')
          self.assertTrue('gaussiansmearingwidth' not in lobsterin_new)
  
          # fatband and ISMEAR=-5 does not work together
          with self.assertRaises(ValueError):
              lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(
                  os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                  os.path.join(test_dir_doscar, "INCAR.lobster2"),
                  dict_for_basis={"Fe": '3d 4p 4s', "O": '2s 2p'},
                  option='standard_with_fatband')
  
      def test_diff(self):
          # test diff
          self.assertDictEqual(self.Lobsterinfromfile.diff(self.Lobsterinfromfile2)["Different"], {})
          self.assertAlmostEqual(self.Lobsterinfromfile.diff(self.Lobsterinfromfile2)["Same"]["COHPSTARTENERGY"], -15.0)
  
          # test diff in both directions
          for entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Same"].keys():
              self.assertTrue(entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Same"].keys())
          for entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Same"].keys():
              self.assertTrue(entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Same"].keys())
          for entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"].keys():
              self.assertTrue(entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"].keys())
          for entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"].keys():
              self.assertTrue(entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"].keys())
  
          self.assertEqual(self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"]["SKIPCOHP"]["lobsterin1"],
                           self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"]["SKIPCOHP"]["lobsterin2"])
  
      def test_get_basis(self):
          # get basis functions
          lobsterin1 = Lobsterin({})
          potcar = Potcar.from_file(os.path.join(test_dir_doscar, "POTCAR.Fe3O4"))
          Potcar_names = [name["symbol"] for name in potcar.spec]
  
          self.assertListEqual(lobsterin1.get_basis(Structure.from_file(os.path.join(test_dir_doscar, "Fe3O4.cif")),
                                                    potcar_symbols=Potcar_names),
                               ['Fe 3d 4p 4s ', 'O 2p 2s '])
          potcar = Potcar.from_file(os.path.join(test_dir, "POTCAR.GaAs"))
          Potcar_names = [name["symbol"] for name in potcar.spec]
          self.assertListEqual(lobsterin1.get_basis(Structure.from_file(os.path.join(test_dir, "POSCAR.GaAs")),
                                                    potcar_symbols=Potcar_names),
                               ['Ga 3d 4p 4s ', 'As 4p 4s '])
  
      def test_get_all_possible_basis_functions(self):
          potcar = Potcar.from_file(os.path.join(test_dir_doscar, "POTCAR.Fe3O4"))
          Potcar_names = [name["symbol"] for name in potcar.spec]
          result = Lobsterin.get_all_possible_basis_functions(
              Structure.from_file(os.path.join(test_dir_doscar, "Fe3O4.cif")),
              potcar_symbols=Potcar_names)
          self.assertDictEqual(result[0], {'Fe': '3d 4s', 'O': '2p 2s'})
          self.assertDictEqual(result[1], {'Fe': '3d 4s 4p', 'O': '2p 2s'})
  
          potcar2 = Potcar.from_file(os.path.join(test_dir_doscar, "POT_GGA_PAW_PBE_54/POTCAR.Fe_pv.gz"))
          Potcar_names2 = [name["symbol"] for name in potcar2.spec]
          result2 = Lobsterin.get_all_possible_basis_functions(
              Structure.from_file(os.path.join(test_dir_doscar, "Fe.cif")),
              potcar_symbols=Potcar_names2)
          self.assertDictEqual(result2[0], {'Fe': '3d 3p 4s'})
  
      def test_get_potcar_symbols(self):
          lobsterin1 = Lobsterin({})
          self.assertListEqual(lobsterin1._get_potcar_symbols(os.path.join(test_dir_doscar, "POTCAR.Fe3O4")), ['Fe', 'O'])
          self.assertListEqual(lobsterin1._get_potcar_symbols(os.path.join(test_dir, "POTCAR.GaAs")), ['Ga_d', 'As'])
  
      def test_write_lobsterin(self):
          # write lobsterin, read it and compare it
          outfile_path = tempfile.mkstemp()[1]
          lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                                       os.path.join(test_dir_doscar, "INCAR.lobster"),
                                                                       os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
                                                                       option='standard')
          lobsterin1.write_lobsterin(outfile_path)
          lobsterin2 = Lobsterin.from_file(outfile_path)
          self.assertDictEqual(lobsterin1.diff(lobsterin2)["Different"], {})
  
      def test_write_INCAR(self):
          # write INCAR and compare
          outfile_path = tempfile.mkstemp()[1]
          lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                                       os.path.join(test_dir_doscar, "INCAR.lobster"),
                                                                       os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
                                                                       option='standard')
          lobsterin1.write_INCAR(os.path.join(test_dir_doscar, "INCAR.lobster3"), outfile_path,
                                 os.path.join(test_dir_doscar, "POSCAR.Fe3O4"))
  
          incar1 = Incar.from_file(os.path.join(test_dir_doscar, "INCAR.lobster3"))
          incar2 = Incar.from_file(outfile_path)
  
          self.assertDictEqual(incar1.diff(incar2)["Different"],
                               {'ISYM': {'INCAR1': 2, 'INCAR2': -1}, 'NBANDS': {'INCAR1': None, 'INCAR2': 86},
                                'NSW': {'INCAR1': 500, 'INCAR2': 0}, "LWAVE": {"INCAR1": False, "INCAR2": True}})
  
      def test_write_KPOINTS(self):
  
          # line mode
          outfile_path = tempfile.mkstemp()[1]
          outfile_path2 = tempfile.mkstemp(prefix='POSCAR')[1]
          lobsterin1 = Lobsterin({})
          # test writing primitive cell
          lobsterin1.write_POSCAR_with_standard_primitive(POSCAR_input=os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
                                                          POSCAR_output=outfile_path2)
  
          lobsterin1.write_KPOINTS(POSCAR_input=outfile_path2, KPOINTS_output=outfile_path, kpoints_line_density=58)
          kpoint = Kpoints.from_file(outfile_path)
          self.assertEqual(kpoint.num_kpts, 562)
          self.assertAlmostEqual(kpoint.kpts[-1][0], -0.5)
          self.assertAlmostEqual(kpoint.kpts[-1][1], 0.5)
          self.assertAlmostEqual(kpoint.kpts[-1][2], 0.5)
          self.assertEqual(kpoint.labels[-1], 'T')
          kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "KPOINTS_band.lobster"))
  
          labels = []
          number = 0
          for label in kpoint.labels:
              if label is not None:
                  if number != 0:
                      if label != labels[number - 1]:
                          labels.append(label)
                          number += 1
                  else:
                      labels.append(label)
                      number += 1
  
          labels2 = []
          number2 = 0
          for label in kpoint2.labels:
              if label is not None:
                  if number2 != 0:
                      if label != labels2[number2 - 1]:
                          labels2.append(label)
                          number2 += 1
                  else:
                      labels2.append(label)
                      number2 += 1
          self.assertListEqual(labels, labels2)
  
          # without line mode
          lobsterin1.write_KPOINTS(POSCAR_input=outfile_path2, KPOINTS_output=outfile_path, line_mode=False)
          kpoint = Kpoints.from_file(outfile_path)
          kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "IBZKPT.lobster"))
  
          for num_kpt, list_kpoint in enumerate(kpoint.kpts):
              self.assertAlmostEqual(list_kpoint[0], kpoint2.kpts[num_kpt][0])
              self.assertAlmostEqual(list_kpoint[1], kpoint2.kpts[num_kpt][1])
              self.assertAlmostEqual(list_kpoint[2], kpoint2.kpts[num_kpt][2])
  
          self.assertEqual(kpoint.num_kpts, 108)
  
          # without line mode, use grid instead of reciprocal density
          lobsterin1.write_KPOINTS(POSCAR_input=outfile_path2, KPOINTS_output=outfile_path, line_mode=False,
                                   from_grid=True, input_grid=[6, 6, 3])
          kpoint = Kpoints.from_file(outfile_path)
          kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "IBZKPT.lobster"))
  
          for num_kpt, list_kpoint in enumerate(kpoint.kpts):
              self.assertAlmostEqual(list_kpoint[0], kpoint2.kpts[num_kpt][0])
              self.assertAlmostEqual(list_kpoint[1], kpoint2.kpts[num_kpt][1])
              self.assertAlmostEqual(list_kpoint[2], kpoint2.kpts[num_kpt][2])
  
          self.assertEqual(kpoint.num_kpts, 108)
  
          #
          # #without line mode, using a certain grid, isym=0 instead of -1
          lobsterin1.write_KPOINTS(POSCAR_input=os.path.join(test_dir, "POSCAR.Li"), KPOINTS_output=outfile_path,
                                   line_mode=False,
                                   from_grid=True, input_grid=[3, 3, 3], isym=0)
  
          kpoint1 = Kpoints.from_file(outfile_path)
          kpoint2 = Kpoints.from_file(os.path.join(test_dir, "IBZKPT_3_3_3_Li"))
          for ikpoint, kpoint in enumerate(kpoint1.kpts):
              self.assertTrue(
                  self.is_kpoint_in_list(kpoint, kpoint2.kpts, kpoint1.kpts_weights[ikpoint], kpoint2.kpts_weights))
          for ikpoint, kpoint in enumerate(kpoint2.kpts):
              self.assertTrue(
                  self.is_kpoint_in_list(kpoint, kpoint1.kpts, kpoint2.kpts_weights[ikpoint], kpoint1.kpts_weights))
  
          lobsterin1.write_KPOINTS(POSCAR_input=os.path.join(test_dir, "POSCAR.Li"), KPOINTS_output=outfile_path,
                                   line_mode=False,
                                   from_grid=True, input_grid=[2, 2, 2], isym=0)
  
          kpoint1 = Kpoints.from_file(outfile_path)
          kpoint2 = Kpoints.from_file(os.path.join(test_dir, "IBZKPT_2_2_2_Li"))
          for ikpoint, kpoint in enumerate(kpoint1.kpts):
              self.assertTrue(
                  self.is_kpoint_in_list(kpoint, kpoint2.kpts, kpoint1.kpts_weights[ikpoint], kpoint2.kpts_weights))
          for ikpoint, kpoint in enumerate(kpoint2.kpts):
              self.assertTrue(
                  self.is_kpoint_in_list(kpoint, kpoint1.kpts, kpoint2.kpts_weights[ikpoint], kpoint1.kpts_weights))
  
      def is_kpoint_in_list(self, kpoint, kpointlist, weight, weightlist):
          found = 0
          for ikpoint2, kpoint2 in enumerate(kpointlist):
              if np.isclose(kpoint[0], kpoint2[0]) and np.isclose(kpoint[1], kpoint2[1]) and np.isclose(kpoint[2],
                                                                                                        kpoint2[2]):
                  if weight == weightlist[ikpoint2]:
                      found += 1
              elif np.isclose(-kpoint[0], kpoint2[0]) and np.isclose(-kpoint[1], kpoint2[1]) and np.isclose(-kpoint[2],
                                                                                                            kpoint2[2]):
                  if weight == weightlist[ikpoint2]:
                      found += 1
          if found == 1:
              return True
          else:
              return False
  
      def test_MSONable_implementation(self):
          # tests as dict and from dict methods
          newLobsterin = Lobsterin.from_dict(self.Lobsterinfromfile.as_dict())
          self.assertDictEqual(newLobsterin, self.Lobsterinfromfile)
          newLobsterin.to_json()
  
      def tearDown(self):
          warnings.simplefilter("default")
  
  
  class BandoverlapsTest(unittest.TestCase):
      def setUp(self):
          warnings.simplefilter("ignore")
          # test spin polarlized calc and non spinpolarized calc
  
          self.bandoverlaps1 = Bandoverlaps(os.path.join(test_dir, "bandOverlaps.lobster.1"))
          self.bandoverlaps2 = Bandoverlaps(os.path.join(test_dir, "bandOverlaps.lobster.2"))
  
      def test_attributes(self):
          # bandoverlapsdict
          self.assertAlmostEqual(self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["maxDeviation"], 0.000278953)
          self.assertAlmostEqual(self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][-1][-1], 0.0188058)
          self.assertAlmostEqual(self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][0][0], 1)
  
          self.assertAlmostEqual(
              self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["maxDeviation"], 4.31567e-05)
          self.assertAlmostEqual(
              self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["matrix"][0][-1], 4.0066e-07)
  
          # maxDeviation
          self.assertAlmostEqual(self.bandoverlaps1.max_deviation[0], 0.000278953)
          self.assertAlmostEqual(self.bandoverlaps1.max_deviation[-1], 4.31567e-05)
  
          self.assertAlmostEqual(self.bandoverlaps2.max_deviation[0], 0.000473319)
          self.assertAlmostEqual(self.bandoverlaps2.max_deviation[-1], 1.48451e-05)
  
      def test_has_good_quality(self):
          self.assertFalse(self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=0.1))
          self.assertFalse(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=9,
                                                                                    number_occ_bands_spin_down=5,
                                                                                    limit_deviation=0.1,
                                                                                    spin_polarized=True))
          self.assertTrue(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=3,
                                                                                   number_occ_bands_spin_down=0,
                                                                                   limit_deviation=0.001,
                                                                                   spin_polarized=True))
          self.assertFalse(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1,
                                                                                    number_occ_bands_spin_down=1,
                                                                                    limit_deviation=0.000001,
                                                                                    spin_polarized=True))
          self.assertFalse(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1,
                                                                                    number_occ_bands_spin_down=0,
                                                                                    limit_deviation=0.000001,
                                                                                    spin_polarized=True))
          self.assertFalse(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=0,
                                                                                    number_occ_bands_spin_down=1,
                                                                                    limit_deviation=0.000001,
                                                                                    spin_polarized=True))
          self.assertFalse(self.bandoverlaps1.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=4,
                                                                                    number_occ_bands_spin_down=4,
                                                                                    limit_deviation=0.001,
                                                                                    spin_polarized=True))
  
          self.assertTrue(self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=100))
          self.assertTrue(self.bandoverlaps2.has_good_quality_maxDeviation())
          self.assertFalse(self.bandoverlaps2.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001))
          self.assertFalse(self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=10,
                                                                                    limit_deviation=0.0000001))
          self.assertTrue(
              self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1))
  
          self.assertFalse(
              self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=1e-8))
          self.assertTrue(
              self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=10, limit_deviation=0.1))
  
          self.assertTrue(
              self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1))
  
  
  class GrosspopTest(unittest.TestCase):
      def setUp(self):
          self.grosspop1 = Grosspop(os.path.join(test_dir, "GROSSPOP.lobster"))
  
      def testattributes(self):
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3s"], 0.52)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_y"], 0.38)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_z"], 0.37)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_x"], 0.37)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["total"], 1.64)
          self.assertEqual(self.grosspop1.list_dict_grosspop[0]["element"], 'Si')
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3s"], 0.61)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_y"], 0.52)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_z"], 0.52)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_x"], 0.52)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["total"], 2.16)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[5]["Mulliken GP"]["2s"], 1.80)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[5]["Loewdin GP"]["2s"], 1.60)
          self.assertEqual(self.grosspop1.list_dict_grosspop[5]["element"], 'O')
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[8]["Mulliken GP"]["2s"], 1.80)
          self.assertAlmostEqual(self.grosspop1.list_dict_grosspop[8]["Loewdin GP"]["2s"], 1.60)
          self.assertEqual(self.grosspop1.list_dict_grosspop[8]["element"], 'O')
  
      def test_structure_with_grosspop(self):
          struct_dict = {'@module': 'pymatgen.core.structure', '@class': 'Structure', 'charge': None, 'lattice': {
              'matrix': [[5.021897888834907, 4.53806e-11, 0.0], [-2.5109484443388332, 4.349090983701526, 0.0],
                         [0.0, 0.0, 5.511929408565514]], 'a': 5.021897888834907, 'b': 5.0218974974248045,
              'c': 5.511929408565514, 'alpha': 90.0, 'beta': 90.0, 'gamma': 119.99999598960493,
              'volume': 120.38434608659402}, 'sites': [
              {'species': [{'element': 'Si', 'occu': 1}], 'abc': [-3e-16, 0.4763431475490085, 0.6666669999999968],
               'xyz': [-1.1960730853096477, 2.0716596881533986, 3.674621443020128], 'label': 'Si',
               'properties': {'Total Mulliken GP': 1.64, 'Total Loewdin GP': 2.16}},
              {'species': [{'element': 'Si', 'occu': 1}], 'abc': [0.5236568524509936, 0.5236568524509926, 0.0],
               'xyz': [1.3148758827683875, 2.277431295571896, 0.0], 'label': 'Si',
               'properties': {'Total Mulliken GP': 1.64, 'Total Loewdin GP': 2.16}},
              {'species': [{'element': 'Si', 'occu': 1}], 'abc': [0.4763431475490066, -1.2e-15, 0.3333330000000032],
               'xyz': [2.392146647037334, 2.1611518932482004e-11, 1.8373079655453863], 'label': 'Si',
               'properties': {'Total Mulliken GP': 1.64, 'Total Loewdin GP': 2.16}},
              {'species': [{'element': 'O', 'occu': 1}],
               'abc': [0.1589037798059321, 0.7440031622164922, 0.4613477252144715],
               'xyz': [-1.0701550264153763, 3.235737444648381, 2.5429160941844473], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}},
              {'species': [{'element': 'O', 'occu': 1}],
               'abc': [0.2559968377835071, 0.4149006175894398, 0.7946807252144676],
               'xyz': [0.2437959189219816, 1.8044405351020447, 4.380224059729795], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}},
              {'species': [{'element': 'O', 'occu': 1}],
               'abc': [0.5850993824105679, 0.8410962201940679, 0.1280147252144683],
               'xyz': [0.8263601076506712, 3.6580039876980064, 0.7056081286390611], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}},
              {'species': [{'element': 'O', 'occu': 1}],
               'abc': [0.7440031622164928, 0.1589037798059326, 0.5386522747855285],
               'xyz': [3.337308710918233, 0.6910869960638374, 2.969013314381067], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}},
              {'species': [{'element': 'O', 'occu': 1}], 'abc': [0.4149006175894392, 0.2559968377835, 0.2053192747855324],
               'xyz': [1.4407936739605638, 1.1133535390791505, 1.13170534883572], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}},
              {'species': [{'element': 'O', 'occu': 1}],
               'abc': [0.841096220194068, 0.5850993824105675, 0.8719852747855317],
               'xyz': [2.754744948452184, 2.5446504486493, 4.806321279926453], 'label': 'O',
               'properties': {'Total Mulliken GP': 7.18, 'Total Loewdin GP': 6.92}}]}
  
          newstructure = self.grosspop1.get_structure_with_total_grosspop(os.path.join(test_dir, "POSCAR.SiO2"))
          for coords, coords2 in zip(newstructure.frac_coords, Structure.from_dict(struct_dict).frac_coords):
              for xyz, xyz2 in zip(coords, coords2):
                  self.assertAlmostEqual(xyz, xyz2)
  
  
  class TestUtils(PymatgenTest):
  
      def test_get_all_possible_basis_combinations(self):
          # this basis is just for testing (not correct)
          min_basis = ['Li 1s 2s ', 'Na 1s 2s', 'Si 1s 2s']
          max_basis = ['Li 1s 2p 2s ', 'Na 1s 2p 2s', 'Si 1s 2s']
          combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
          self.assertListEqual(combinations_basis,
                               [['Li 1s 2s', 'Na 1s 2s', 'Si 1s 2s'], ['Li 1s 2s', 'Na 1s 2s 2p', 'Si 1s 2s'],
                                ['Li 1s 2s 2p', 'Na 1s 2s', 'Si 1s 2s'], ['Li 1s 2s 2p', 'Na 1s 2s 2p', 'Si 1s 2s']])
  
          min_basis = ['Li 1s 2s']
          max_basis = ['Li 1s 2s 2p 3s']
          combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
          self.assertListEqual(combinations_basis, [['Li 1s 2s'], ['Li 1s 2s 2p'], ['Li 1s 2s 3s'], ['Li 1s 2s 2p 3s']])
  
          min_basis = ['Li 1s 2s', 'Na 1s 2s']
          max_basis = ['Li 1s 2s 2p 3s', 'Na 1s 2s 2p 3s']
          combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
          self.assertListEqual(combinations_basis,
                               [['Li 1s 2s', 'Na 1s 2s'], ['Li 1s 2s', 'Na 1s 2s 2p'], ['Li 1s 2s', 'Na 1s 2s 3s'],
                                ['Li 1s 2s', 'Na 1s 2s 2p 3s'], ['Li 1s 2s 2p', 'Na 1s 2s'],
                                ['Li 1s 2s 2p', 'Na 1s 2s 2p'], ['Li 1s 2s 2p', 'Na 1s 2s 3s'],
                                ['Li 1s 2s 2p', 'Na 1s 2s 2p 3s'], ['Li 1s 2s 3s', 'Na 1s 2s'],
                                ['Li 1s 2s 3s', 'Na 1s 2s 2p'], ['Li 1s 2s 3s', 'Na 1s 2s 3s'],
                                ['Li 1s 2s 3s', 'Na 1s 2s 2p 3s'], ['Li 1s 2s 2p 3s', 'Na 1s 2s'],
                                ['Li 1s 2s 2p 3s', 'Na 1s 2s 2p'], ['Li 1s 2s 2p 3s', 'Na 1s 2s 3s'],
                                ['Li 1s 2s 2p 3s', 'Na 1s 2s 2p 3s']])
  
          min_basis = ['Si 1s 2s 2p', 'Na 1s 2s']
          max_basis = ['Si 1s 2s 2p 3s', 'Na 1s 2s 2p 3s']
          combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
          self.assertListEqual(combinations_basis, [['Si 1s 2s 2p', 'Na 1s 2s'], ['Si 1s 2s 2p', 'Na 1s 2s 2p'],
                                                    ['Si 1s 2s 2p', 'Na 1s 2s 3s'], ['Si 1s 2s 2p', 'Na 1s 2s 2p 3s'],
                                                    ['Si 1s 2s 2p 3s', 'Na 1s 2s'], ['Si 1s 2s 2p 3s', 'Na 1s 2s 2p'],
                                                    ['Si 1s 2s 2p 3s', 'Na 1s 2s 3s'],
                                                    ['Si 1s 2s 2p 3s', 'Na 1s 2s 2p 3s']])
  
  
  if __name__ == "__main__":
      unittest.main()
  