예제 #1
0
    def test_utils(self):
        """Test utilities for the generation of Abinit inputs."""
        # Test as_structure and from/to abivars
        si = Structure.as_structure(abidata.cif_file("si.cif"))
        assert si.formula == "Si2"
        assert si.latex_formula == "Si$_{2}$"
        assert si.abi_spacegroup is None and not si.has_abi_spacegroup
        assert "ntypat" in si.to(fmt="abivars")

        spgroup = si.spgset_abi_spacegroup(has_timerev=True)
        assert spgroup is not None
        assert si.has_abi_spacegroup
        assert si.abi_spacegroup.spgid == 227
        kfrac_coords = si.get_kcoords_from_names(["G", "X", "L", "Gamma"])
        self.assert_equal(kfrac_coords,
            ([[0. , 0. , 0. ], [0.5, 0. , 0.5], [0.5, 0.5, 0.5], [0. , 0. , 0. ]]))

        si_wfk = Structure.as_structure(abidata.ref_file("si_scf_WFK.nc"))
        assert si_wfk.formula == "Si2"
        si_wfk.print_neighbors(radius=2.5)

        assert si_wfk.has_abi_spacegroup
        # Cannot change spacegroup
        with self.assertRaises(ValueError):
            si_wfk.spgset_abi_spacegroup(has_timerev=True)

        # K and U are equivalent. [5/8, 1/4, 5/8] should return U
        assert si_wfk.findname_in_hsym_stars([3/8, 3/8, 3/4]) == "K"
        assert si_wfk.findname_in_hsym_stars([5/8, 1/4, 5/8]) == "U"

        # TODO: Fix order of atoms in supercells.
        # Test __mul__, __rmul__ (should return Abipy structures)
        assert si_wfk == 1 * si_wfk
        supcell = si_wfk * [2, 2, 2]
        assert len(supcell) == 8 * len(si_wfk) and hasattr(supcell, "abi_string")

        si_abi = Structure.from_file(abidata.ref_file("refs/si_ebands/run.abi"))
        assert si_abi.formula == "Si2"
        self.assert_equal(si_abi.frac_coords, [[0, 0, 0], [0.25, 0.25, 0.25]])

        si_abo = Structure.from_file(abidata.ref_file("refs/si_ebands/run.abo"))
        assert si_abo == si_abi
        assert "ntypat" in si_abi.to(fmt="abivars")

        znse = Structure.from_file(abidata.ref_file("refs/znse_phonons/ZnSe_hex_qpt_DDB"))
        assert len(znse) == 4
        assert znse.formula == "Zn2 Se2"
        self.assert_almost_equal(znse.frac_coords.flat, [
            0.33333333333333,  0.66666666666667, 0.99962203020000,
            0.66666666666667,  0.33333333333333, 0.49962203020000,
            0.33333333333333,  0.66666666666667, 0.62537796980000,
            0.66666666666667,  0.33333333333333, 0.12537796980000])

        from abipy.core.structure import diff_structures
        diff_structures([si_abi, znse], headers=["si_abi", "znse"], fmt="abivars", mode="table")
        diff_structures([si_abi, znse], headers=["si_abi", "znse"], fmt="abivars", mode="diff")

        # From pickle file.
        import pickle
        tmp_path = self.get_tmpname(suffix=".pickle")
        with open(tmp_path, "wb") as fh:
            pickle.dump(znse, fh)
        same_znse = Structure.from_file(tmp_path)
        assert same_znse == znse
        same_znse = Structure.as_structure(tmp_path)
        assert same_znse == znse

        for fmt in ["abivars", "cif", "POSCAR", "json", "xsf", "qe", "siesta", "wannier90"]:
            assert len(znse.convert(fmt=fmt)) > 0

        for fmt in ["abinit", "w90", "siesta"]:
            assert len(znse.get_kpath_input_string(fmt=fmt)) > 0

        oxi_znse = znse.get_oxi_state_decorated()
        assert len(oxi_znse.abi_string)
        from pymatgen.core.periodic_table import Specie
        assert Specie("Zn", 2) in oxi_znse.composition.elements
        assert Specie("Se", -2) in oxi_znse.composition.elements

        system = si.spget_lattice_type()
        assert system == "cubic"

        e = si.spget_equivalent_atoms(printout=True)
        assert len(e.irred_pos) == 1
        self.assert_equal(e.eqmap[0], [0, 1])
        for irr_pos in e.irred_pos:
            assert len(e.eqmap[irr_pos]) > 0
        assert "equivalent_atoms" in e.spgdata

        if self.has_matplotlib():
            assert si.plot_bz(show=False)
            assert si.plot_bz(pmg_path=False, show=False)
            assert si.plot(show=False)
            if sys.version[0:3] > '2.7':
                # pmg broke py compatibility
                assert si.plot_xrd(show=False)

        if self.has_mayavi():
            #assert si.plot_vtk(show=False)  # Disabled due to (core dumped) on travis
            assert si.plot_mayaview(show=False)

        if self.has_panel():
            assert hasattr(si.get_panel(), "show")

        assert si is Structure.as_structure(si)
        assert si == Structure.as_structure(si.to_abivars())
        assert si == Structure.from_abivars(si.to_abivars())
        assert len(si.abi_string)
        assert si.reciprocal_lattice == si.lattice.reciprocal_lattice

        kptbounds = si.calc_kptbounds()
        ksamp = si.calc_ksampling(nksmall=10)

        shiftk = [[ 0.5,  0.5,  0.5], [ 0.5,  0. ,  0. ], [ 0. ,  0.5,  0. ], [ 0. ,  0. ,  0.5]]
        self.assert_equal(si.calc_ngkpt(nksmall=2), [2, 2, 2])
        self.assert_equal(si.calc_shiftk(), shiftk)
        self.assert_equal(ksamp.ngkpt, [10, 10, 10])
        self.assert_equal(ksamp.shiftk, shiftk)

        lif = Structure.from_abistring("""
acell      7.7030079150    7.7030079150    7.7030079150 Angstrom
rprim      0.0000000000    0.5000000000    0.5000000000
           0.5000000000    0.0000000000    0.5000000000
           0.5000000000    0.5000000000    0.0000000000
natom      2
ntypat     2
typat      1 2
znucl      3 9
xred       0.0000000000    0.0000000000    0.0000000000
           0.5000000000    0.5000000000    0.5000000000
""")
        assert lif.formula == "Li1 F1"
        same = Structure.rocksalt(7.7030079150, ["Li", "F"], units="ang")
        self.assert_almost_equal(lif.lattice.a,  same.lattice.a)

        si = Structure.from_mpid("mp-149")
        assert si.formula == "Si2"

        # Test abiget_spginfo
        d = si.abiget_spginfo(tolsym=None, pre="abi_")
        assert d["abi_spg_symbol"] == "Fd-3m"
        assert d["abi_spg_number"] == 227
        assert d["abi_bravais"] == "Bravais cF (face-center cubic)"

        llzo = Structure.from_file(abidata.cif_file("LLZO_oxi.cif"))
        assert llzo.is_ordered
        d = llzo.abiget_spginfo(tolsym=0.001)
        assert d["spg_number"] == 142

        mgb2_cod = Structure.from_cod_id(1526507, primitive=True)
        assert mgb2_cod.formula == "Mg1 B2"
        assert mgb2_cod.spget_lattice_type() == "hexagonal"

        mgb2 = abidata.structure_from_ucell("MgB2")
        if self.has_ase():
            mgb2.abi_primitive()

        assert [site.species_string for site in mgb2.get_sorted_structure_z()] == ["B", "B", "Mg"]

        s2inds = mgb2.get_symbol2indices()
        self.assert_equal(s2inds["Mg"], [0])
        self.assert_equal(s2inds["B"], [1, 2])

        s2coords = mgb2.get_symbol2coords()
        self.assert_equal(s2coords["Mg"], [[0, 0, 0]])
        self.assert_equal(s2coords["B"],  [[1/3, 2/3, 0.5], [2/3, 1/3, 0.5]])

        new_mgb2 = mgb2.scale_lattice(mgb2.volume * 1.1)
        self.assert_almost_equal(new_mgb2.volume, mgb2.volume * 1.1)
        assert new_mgb2.lattice.is_hexagonal

        # TODO: This part should be tested more carefully
        mgb2.abi_sanitize()
        mgb2.abi_sanitize(primitive_standard=True)
        mgb2.get_conventional_standard_structure()
        assert len(mgb2.abi_string)
        assert len(mgb2.spget_summary(site_symmetry=True, verbose=10))

        self.serialize_with_pickle(mgb2)

        pseudos = abidata.pseudos("12mg.pspnc", "5b.pspnc")
        nv = mgb2.num_valence_electrons(pseudos)
        assert nv == 8 and isinstance(nv , int)
        assert mgb2.valence_electrons_per_atom(pseudos) == [2, 3, 3]
        self.assert_equal(mgb2.calc_shiftk() , [[0.0, 0.0, 0.5]])

        bmol = Structure.boxed_molecule(pseudos, cart_coords=[[0, 0, 0], [5, 5, 5]], acell=[10, 10, 10])
        self.assert_almost_equal(bmol.volume, (10 * bohr_to_ang) ** 3)

        # FIXME This is buggy
        #acell = np.array([10, 20, 30])
        #batom = Structure.boxed_atom(abidata.pseudo("12mg.pspnc"), cart_coords=[1, 2, 3], acell=acell)
        #assert isinstance(batom, Structure)
        #assert len(batom.cart_coords) == 1
        #self.assert_equal(batom.cart_coords[0], [1, 2, 3])

        # Function to compute cubic a0 from primitive v0 (depends on struct_type)
        vol2a = {"fcc": lambda vol: (4 * vol) ** (1/3.),
                 "bcc": lambda vol: (2 * vol) ** (1/3.),
                 "zincblende": lambda vol: (4 * vol) ** (1/3.),
                 "rocksalt": lambda vol: (4 * vol) ** (1/3.),
                 "ABO3": lambda vol: vol ** (1/3.),
                 "hH": lambda vol: (4 * vol) ** (1/3.),
                 }

        a = 10
        bcc_prim = Structure.bcc(a, ["Si"], primitive=True)
        assert len(bcc_prim) == 1
        self.assert_almost_equal(a, vol2a["bcc"](bcc_prim.volume))
        bcc_conv = Structure.bcc(a, ["Si"], primitive=False)
        assert len(bcc_conv) == 2
        self.assert_almost_equal(a**3, bcc_conv.volume)
        fcc_prim = Structure.fcc(a, ["Si"], primitive=True)
        assert len(fcc_prim) == 1
        self.assert_almost_equal(a, vol2a["fcc"](fcc_prim.volume))
        fcc_conv = Structure.fcc(a, ["Si"], primitive=False)
        assert len(fcc_conv) == 4
        self.assert_almost_equal(a**3, fcc_conv.volume)
        zns = Structure.zincblende(a / bohr_to_ang, ["Zn", "S"], units="bohr")
        self.assert_almost_equal(a, vol2a["zincblende"](zns.volume))
        rock = Structure.rocksalt(a, ["Na", "Cl"])
        assert len(rock) == 2
        self.assert_almost_equal(a, vol2a["rocksalt"](rock.volume))
        perov = Structure.ABO3(a, ["Ca", "Ti", "O", "O", "O"])
        assert len(perov) == 5
        self.assert_almost_equal(a**3, perov.volume)

        # Test notebook generation.
        if self.has_nbformat():
            assert mgb2.write_notebook(nbpath=self.get_tmpname(text=True))
예제 #2
0
파일: abistruct.py 프로젝트: gonzex/abipy
def main():
    def show_examples_and_exit(err_msg=None, error_code=1):
        """Display the usage of the script."""
        sys.stderr.write(get_epilog())
        if err_msg: sys.stderr.write("Fatal Error\n" + err_msg + "\n")
        sys.exit(error_code)

    parser = get_parser(with_epilog=True)

    # Parse command line.
    try:
        options = parser.parse_args()
    except Exception as exc:
        show_examples_and_exit(error_code=1)

    if not options.command:
        show_examples_and_exit(error_code=1)

    # loglevel is bound to the string value obtained from the command line argument.
    # Convert to upper case to allow the user to specify --loglevel=DEBUG or --loglevel=debug
    import logging
    numeric_level = getattr(logging, options.loglevel.upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError('Invalid log level: %s' % options.loglevel)
    logging.basicConfig(level=numeric_level)

    if options.verbose > 2:
        print(options)

    if options.command == "spglib":
        structure = abilab.Structure.from_file(options.filepath)
        print(
            structure.spget_summary(symprec=options.symprec,
                                    angle_tolerance=options.angle_tolerance,
                                    verbose=options.verbose))
        #remove_equivalent_atoms(structure)

    elif options.command == "abispg":
        structure = abilab.Structure.from_file(options.filepath)
        spgrp = structure.abi_spacegroup

        if spgrp is not None:
            print(structure.spget_summary(verbose=options.verbose))
        else:
            # Here we compare Abinit wrt spglib. If spgrp is None, we create a temporary
            # task to run the code in dry-run mode.
            print("FILE does not contain Abinit symmetry operations.")
            print(
                "Calling Abinit in --dry-run mode with chkprim = 0 to get space group."
            )
            from abipy.data.hgh_pseudos import HGH_TABLE
            gsinp = factories.gs_input(structure,
                                       HGH_TABLE,
                                       spin_mode="unpolarized")
            gsinp["chkprim"] = 0
            abistructure = gsinp.abiget_spacegroup(tolsym=options.tolsym)
            print(abistructure.spget_summary(verbose=options.verbose))

            diff_structures(
                [structure, abistructure],
                mode=options.diff_mode,
                headers=["Input structure", "After Abinit symmetrization"],
                fmt="abivars")

            # Save file.
            save_structure(abistructure, options)

    elif options.command == "convert":
        fmt = options.format
        if fmt == "cif" and options.filepath.endswith(".cif"): fmt = "abivars"
        print(abilab.Structure.from_file(options.filepath).convert(fmt=fmt))

    elif options.command == "supercell":
        structure = abilab.Structure.from_file(options.filepath)

        options.scaling_matrix = np.array(options.scaling_matrix)
        if len(options.scaling_matrix) == 9:
            options.scaling_matrix.shape = (3, 3)
        if options.verbose:
            print("scaling matrix: ", options.scaling_matrix)

        supcell = structure * options.scaling_matrix
        #supcell = structure.make_supercell(scaling_matrix, to_unit_cell=True)
        print(supcell.convert(fmt=options.format))

    elif options.command == "abisanitize":
        print("\nCalling abi_sanitize to get a new structure in which:")
        print("    * Structure is refined.")
        print("    * Reduced to primitive settings.")
        print(
            "    * Lattice vectors are exchanged if the triple product is negative\n"
        )

        structure = abilab.Structure.from_file(options.filepath)
        sanitized = structure.abi_sanitize(
            symprec=options.symprec,
            angle_tolerance=options.angle_tolerance,
            primitive=not options.no_primitive,
            primitive_standard=options.primitive_standard)
        index = [options.filepath, "abisanitized"]
        dfs = abilab.dataframes_from_structures([structure, sanitized],
                                                index=index,
                                                with_spglib=True)

        abilab.print_dataframe(dfs.lattice, title="Lattice parameters:")
        abilab.print_dataframe(
            dfs.coords,
            title="Atomic positions (columns give the site index):")

        if not options.verbose:
            print("\nUse -v for more info")
            #print(sanitized.convert(fmt="cif"))
        else:
            #print("\nDifference between structures:")
            if len(structure) == len(sanitized):
                table = []
                for line1, line2 in zip(
                        str(structure).splitlines(),
                        str(sanitized).splitlines()):
                    table.append([line1, line2])
                print(
                    str(
                        tabulate(table,
                                 headers=["Initial structure",
                                          "Abisanitized"])))

            else:
                print("\nInitial structure:")
                print(structure)
                print("\nabisanitized structure:")
                print(sanitized)

        # Save file.
        save_structure(sanitized, options)

    elif options.command == "irefine":
        structure = abilab.Structure.from_file(options.filepath)
        sanitized = structure.copy()
        symprec, angle_tolerance = options.symprec, options.angle_tolerance
        print(
            "Calling abi_sanitize with increasing tolerances to reach target space group:",
            options.target_spgnum)
        print("Using symprec_step: ", options.symprec_step,
              ", angle_tolerance_step:", options.angle_tolerance_step,
              "ntrial", options.ntrial)
        itrial = 0
        while itrial < options.ntrial:
            print(">>> Trying with symprec: %s, angle_tolerance: %s" %
                  (symprec, angle_tolerance))
            sanitized = sanitized.abi_sanitize(
                symprec=symprec,
                angle_tolerance=angle_tolerance,
                primitive=not options.no_primitive,
                primitive_standard=options.primitive_standard)
            spg_symb, spg_num = sanitized.get_space_group_info(
                symprec=symprec, angle_tolerance=angle_tolerance)
            print(">>> Space-group number:", spg_symb, ", symbol:", spg_num,
                  "for trial:", itrial)
            if spg_num == options.target_spgnum:
                print(2 * "\n", "# Final structure with space group number:",
                      spg_symb, ", symbol:", spg_num, 2 * "\n")
                print(sanitized.convert(fmt="cif"))
                break

            # Increment counter and tols.
            itrial += 1
            symprec += options.symprec_step
            angle_tolerance += options.angle_tolerance_step
        else:
            print("Cannot find space group number:", options.target_spgnum,
                  "after", options.ntrial, "iterations")
            return 1

        # Save file.
        #save_structure(sanitized, options)

    elif options.command == "conventional":
        print(
            "\nCalling get_conventional_standard_structure to get conventional structure:"
        )
        print(
            "The standards are defined in Setyawan, W., & Curtarolo, S. (2010). "
        )
        print(
            "High-throughput electronic band structure calculations: Challenges and tools. "
        )
        print(
            "Computational Materials Science, 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010\n"
        )

        structure = abilab.Structure.from_file(options.filepath)
        conv = structure.get_conventional_standard_structure(
            international_monoclinic=True,
            symprec=options.symprec,
            angle_tolerance=options.angle_tolerance)
        index = [options.filepath, "conventional"]
        dfs = abilab.dataframes_from_structures([structure, conv],
                                                index=index,
                                                with_spglib=True)

        abilab.print_dataframe(dfs.lattice, title="Lattice parameters:")
        if options.verbose:
            abilab.print_dataframe(
                dfs.coords,
                title="Atomic positions (columns give the site index):")

        if not options.verbose:
            print("\nUse -v for more info")
        else:
            #print("\nDifference between structures:")
            if len(structure) == len(conv):
                table = []
                for line1, line2 in zip(
                        str(structure).splitlines(),
                        str(conv).splitlines()):
                    table.append([line1, line2])
                print(
                    str(
                        tabulate(table,
                                 headers=["Initial structure",
                                          "Conventional"])))

            else:
                print("\nInitial structure:\n", structure)
                print("\nConventional structure:\n", conv)

        # Save file.
        save_structure(conv, options)

    elif options.command == "neighbors":
        abilab.Structure.from_file(
            options.filepath).print_neighbors(radius=options.radius)

    elif options.command == "interpolate":
        initial_structure = abilab.Structure.from_file(options.filepaths[0])
        end_structure = abilab.Structure.from_file(options.filepaths[1])
        structures = initial_structure.interpolate(
            end_structure,
            nimages=options.nimages,
            interpolate_lattices=False,
            pbc=True,
            autosort_tol=options.autosort_tol)
        structures = list(map(abilab.Structure.as_structure, structures))
        for i, s in enumerate(structures):
            print(marquee("Structure #%d" % i, mark="="))
            print(s.convert(fmt=options.format))
            print(" ")

    elif options.command == "xrd":
        structure = abilab.Structure.from_file(options.filepath)
        two_theta_range = tuple(float(t) for t in options.two_theta_range)
        structure.plot_xrd(wavelength=options.wavelength,
                           two_theta_range=two_theta_range,
                           symprec=options.symprec,
                           annotate_peaks=not options.no_annotate_peaks)

    elif options.command == "oxistate":
        print(
            abilab.Structure.from_file(
                options.filepath).get_oxi_state_decorated())

    elif options.command == "ipython":
        structure = abilab.Structure.from_file(options.filepath)
        print(
            "Invoking Ipython, `structure` object will be available in the Ipython terminal"
        )
        import IPython
        IPython.start_ipython(argv=[], user_ns={"structure": structure})

    elif options.command == "notebook":
        structure = abilab.Structure.from_file(options.filepath)
        structure.make_and_open_notebook(nbpath=None,
                                         foreground=options.foreground)

    elif options.command == "visualize":
        structure = abilab.Structure.from_file(options.filepath)
        print(structure)
        print("Visualizing structure with:", options.appname)
        structure.visualize(appname=options.appname)

    elif options.command == "kpath":
        structure = abilab.Structure.from_file(options.filepath)
        print("# Abinit Structure")
        print(structure.abi_string)
        print("\n# K-path in reduced coordinates:")
        print("# tolwfr 1e-20 iscf -2 getden ??")
        print(" ndivsm 10")
        print(" kptopt", -(len(structure.hsym_kpoints) - 1))
        print(" kptbounds")
        for k in structure.hsym_kpoints:
            print("    %+.5f  %+.5f  %+.5f" % tuple(k.frac_coords), "#",
                  k.name)

    elif options.command == "bz":
        abilab.Structure.from_file(options.filepath).plot_bz()

    elif options.command == "ngkpt":
        d = abilab.Structure.from_file(options.filepath).calc_ksampling(
            options.nksmall)
        print("ngkpt %d %d %d" % (d.ngkpt[0], d.ngkpt[1], d.ngkpt[2]))
        print("nshiftk ", len(d.shiftk), "\nshiftk")
        for s in d.shiftk:
            print("  %s %s %s" % (s[0], s[1], s[2]))

    elif options.command == "ktables":
        structure = abilab.Structure.from_file(options.filepath)
        k = Ktables(structure, options.mesh, options.is_shift,
                    not options.no_time_reversal)
        print(k)
        print("")
        print(
            "NB: These results are obtained by calling spglib with the structure read from file."
        )
        print(
            "The k-points might differ from the ones expected by Abinit, especially if the space groups differ."
        )

        if not options.verbose:
            print("\nUse -v to obtain the BZ --> IBZ mapping.")
        else:
            print()
            k.print_bz2ibz()

    elif options.command == "abikmesh":
        structure = abilab.Structure.from_file(options.filepath)
        from abipy.data.hgh_pseudos import HGH_TABLE
        gsinp = factories.gs_input(structure,
                                   HGH_TABLE,
                                   spin_mode="unpolarized",
                                   kppa=options.kppa)
        if options.kppa is not None:
            print("Calling Abinit to compute the IBZ with kppa:", options.kppa,
                  "and shiftk:", options.shiftk)
            options.ngkpt = None
        else:
            print("Calling Abinit to compute the IBZ with ngkpt:",
                  options.ngkpt, "and shiftk", options.shiftk)
        ibz = gsinp.abiget_ibz(ngkpt=options.ngkpt,
                               shiftk=options.shiftk,
                               kptopt=options.kptopt)
        if options.verbose:
            print(gsinp)

        print("Found %d points in the IBZ:" % len(ibz.points))
        for i, (k, w) in enumerate(zip(ibz.points, ibz.weights)):
            print("%6d) [%+.3f, %+.3f, %+.3f]  weight=%.3f" %
                  (i, k[0], k[1], k[2], w))

    #elif options.command == "kmesh_jhu":
    #    structure = abilab.Structure.from_file(options.filepath)
    #    ksampling = structure.ksampling_from_jhudb(kppra=1000)
    #    #print(ksampling)

    elif options.command == "lgk":
        structure = abilab.Structure.from_file(options.filepath)
        spgrp = structure.abi_spacegroup
        if spgrp is None:
            cprint("Your file does not contain Abinit symmetry operations.",
                   "yellow")
            cprint(
                "Will call spglib to obtain the space group (assuming time-reversal: %s)"
                % (not options.no_time_reversal), "yellow")
            spgrp = AbinitSpaceGroup.from_structure(
                structure,
                has_timerev=not options.no_time_reversal,
                symprec=options.symprec,
                angle_tolerance=options.angle_tolerance)
        print()
        print(marquee("Structure", mark="="))
        print(structure.spget_summary(verbose=options.verbose))
        print("\n")

        print(marquee("Little Group", mark="="))
        ltk = spgrp.find_little_group(kpoint=options.kpoint)
        print(ltk.to_string(verbose=options.verbose))

    elif options.command == "kstar":
        structure = abilab.Structure.from_file(options.filepath)

        # TODO
        #kstar = structure.get_star_kpoint(options.kpoint, has_timerev=not options.no_time_reversal)

        # Call spglib to get spacegroup if Abinit spacegroup is not available.
        if structure.abi_spacegroup is None:
            structure.spgset_abi_spacegroup(
                has_timerev=not options.no_time_reversal)

        kpoint = Kpoint(options.kpoint, structure.reciprocal_lattice)
        kstar = kpoint.compute_star(structure.abi_spacegroup, wrap_tows=True)
        print("Found %s points in the star of %s\n" %
              (len(kstar), repr(kpoint)))
        for k in kstar:
            print(4 * " ", repr(k))

    elif options.command == "mp_id":
        # Get the Structure corresponding to material_id.
        structure = abilab.Structure.from_mpid(options.mpid,
                                               final=True,
                                               api_key=options.mapi_key,
                                               endpoint=options.endpoint)
        # Convert to format and print it.
        print(structure.convert(fmt=options.format))

    elif options.command == "mp_match":
        mp = abilab.mp_match_structure(options.filepath)
        if not mp.structures:
            cprint("No structure found in database", "yellow")
            return 1

        if options.notebook:
            return mp.make_and_open_notebook(foreground=options.foreground)
        else:
            mp.print_results(fmt=options.format, verbose=options.verbose)

        if options.browser:
            mp.open_browser(limit=None if options.verbose == 2 else 10)

    elif options.command == "mp_search":
        mp = abilab.mp_search(options.chemsys_formula_id)
        if not mp.structures:
            cprint("No structure found in Materials Project database",
                   "yellow")
            return 1
        if options.select_spgnum:
            mp = mp.filter_by_spgnum(options.select_spgnum)

        if options.notebook:
            return mp.make_and_open_notebook(foreground=options.foreground)
        else:
            mp.print_results(fmt=options.format, verbose=options.verbose)

        if options.browser:
            mp.open_browser(limit=None if options.verbose == 2 else 10)

    elif options.command == "mp_pd":
        if os.path.exists(options.file_or_elements):
            structure = abilab.Structure.from_file(options.file_or_elements)
            elements = structure.symbol_set
        else:
            elements = options.file_or_elements.split("-")

        if options.verbose > 1:
            print("Building phase-diagram for elements:", elements)
        with abilab.restapi.get_mprester(api_key=options.mapi_key,
                                         endpoint=options.endpoint) as rest:
            pdr = rest.get_phasediagram_results(elements)
            pdr.print_dataframes(verbose=options.verbose)
            pdr.plot(show_unstable=options.show_unstable)

    elif options.command == "cod_search":
        cod = abilab.cod_search(options.formula, primitive=options.primitive)
        if not cod.structures:
            cprint("No structure found in COD database", "yellow")
            return 1
        if options.select_spgnum:
            cod = cod.filter_by_spgnum(options.select_spgnum)

        if options.notebook:
            return cod.make_and_open_notebook(foreground=options.foreground)
        else:
            cod.print_results(fmt=options.format, verbose=options.verbose)

    elif options.command == "cod_id":
        # Get the Structure from COD
        structure = abilab.Structure.from_cod_id(options.cod_identifier,
                                                 primitive=options.primitive)
        # Convert to format and print it.
        print(structure.convert(fmt=options.format))

    elif options.command == "animate":
        filepath = options.filepath
        if any(filepath.endswith(ext) for ext in ("HIST", "HIST.nc")):
            with abilab.abiopen(filepath) as hist:
                structures = hist.structures

        elif "XDATCAR" in filepath:
            structures = Xdatcar(filepath).structures
            if not structures:
                raise RuntimeError(
                    "Your Xdatcar contains only one structure. Due to a bug "
                    "in the pymatgen routine, your structures won't be parsed correctly"
                    "Solution: Add another structure at the end of the file.")
        else:
            raise ValueError("Don't know how to handle file %s" % filepath)

        xsf_write_structure(sys.stdout, structures)

    else:
        raise ValueError("Unsupported command: %s" % options.command)

    return 0
예제 #3
0
    def test_utils(self):
        """Test utilities for the generation of Abinit inputs."""
        # Test as_structure and from/to abivars
        si = Structure.as_structure(abidata.cif_file("si.cif"))
        assert si.formula == "Si2"
        assert si.latex_formula == "Si$_{2}$"
        assert si.abi_spacegroup is None and not si.has_abi_spacegroup
        assert "ntypat" in si.to(fmt="abivars")

        spgroup = si.spgset_abi_spacegroup(has_timerev=True)
        assert spgroup is not None
        assert si.has_abi_spacegroup
        assert si.abi_spacegroup.spgid == 227
        kfrac_coords = si.get_kcoords_from_names(["G", "X", "L", "Gamma"])
        self.assert_equal(kfrac_coords,
            ([[0. , 0. , 0. ], [0.5, 0. , 0.5], [0.5, 0.5, 0.5], [0. , 0. , 0. ]]))

        with self.assertRaises(TypeError):
            Structure.as_structure({})
        with self.assertRaises(TypeError):
            Structure.as_structure([])

        si_wfk = Structure.as_structure(abidata.ref_file("si_scf_WFK.nc"))
        assert si_wfk.formula == "Si2"
        si_wfk.print_neighbors(radius=2.5)

        assert si_wfk.has_abi_spacegroup
        # Cannot change spacegroup
        with self.assertRaises(ValueError):
            si_wfk.spgset_abi_spacegroup(has_timerev=True)

        # K and U are equivalent. [5/8, 1/4, 5/8] should return U
        assert si_wfk.findname_in_hsym_stars([3/8, 3/8, 3/4]) == "K"
        assert si_wfk.findname_in_hsym_stars([5/8, 1/4, 5/8]) == "U"

        # TODO: Fix order of atoms in supercells.
        # Test __mul__, __rmul__ (should return Abipy structures)
        assert si_wfk == 1 * si_wfk
        supcell = si_wfk * [2, 2, 2]
        assert len(supcell) == 8 * len(si_wfk) and hasattr(supcell, "abi_string")

        si_abi = Structure.from_file(abidata.ref_file("refs/si_ebands/run.abi"))
        assert si_abi.formula == "Si2"
        self.assert_equal(si_abi.frac_coords, [[0, 0, 0], [0.25, 0.25, 0.25]])

        si_abo = Structure.from_file(abidata.ref_file("refs/si_ebands/run.abo"))
        assert si_abo == si_abi
        assert "ntypat" in si_abi.to(fmt="abivars")

        znse = Structure.from_file(abidata.ref_file("refs/znse_phonons/ZnSe_hex_qpt_DDB"))
        assert len(znse) == 4
        assert znse.formula == "Zn2 Se2"
        self.assert_almost_equal(znse.frac_coords.flat, [
            0.33333333333333,  0.66666666666667, 0.99962203020000,
            0.66666666666667,  0.33333333333333, 0.49962203020000,
            0.33333333333333,  0.66666666666667, 0.62537796980000,
            0.66666666666667,  0.33333333333333, 0.12537796980000])

        from abipy.core.structure import diff_structures
        diff_structures([si_abi, znse], headers=["si_abi", "znse"], fmt="abivars", mode="table")
        diff_structures([si_abi, znse], headers=["si_abi", "znse"], fmt="abivars", mode="diff")

        # From pickle file.
        import pickle
        tmp_path = self.get_tmpname(suffix=".pickle")
        with open(tmp_path, "wb") as fh:
            pickle.dump(znse, fh)
        same_znse = Structure.from_file(tmp_path)
        assert same_znse == znse
        same_znse = Structure.as_structure(tmp_path)
        assert same_znse == znse

        for fmt in ["abivars", "cif", "POSCAR", "json", "xsf", "qe", "siesta", "wannier90"]:
            assert len(znse.convert(fmt=fmt)) > 0

        for fmt in ["abinit", "w90", "siesta"]:
            assert len(znse.get_kpath_input_string(fmt=fmt)) > 0

        oxi_znse = znse.get_oxi_state_decorated()
        assert len(oxi_znse.abi_string)
        from pymatgen.core.periodic_table import Specie
        assert Specie("Zn", 2) in oxi_znse.composition.elements
        assert Specie("Se", -2) in oxi_znse.composition.elements

        system = si.spget_lattice_type()
        assert system == "cubic"

        e = si.spget_equivalent_atoms(printout=True)
        assert len(e.irred_pos) == 1
        self.assert_equal(e.eqmap[0], [0, 1])
        for irr_pos in e.irred_pos:
            assert len(e.eqmap[irr_pos]) > 0
        assert "equivalent_atoms" in e.spgdata

        if self.has_matplotlib():
            assert si.plot_bz(show=False)
            assert si.plot_bz(pmg_path=False, show=False)
            assert si.plot(show=False)
            if sys.version[0:3] > '2.7':
                # pmg broke py compatibility
                assert si.plot_xrd(show=False)

        if self.has_mayavi():
            #assert si.vtkview(show=False)  # Disabled due to (core dumped) on travis
            assert si.mayaview(show=False)

        assert si is Structure.as_structure(si)
        assert si == Structure.as_structure(si.to_abivars())
        assert si == Structure.from_abivars(si.to_abivars())
        assert len(si.abi_string)
        assert si.reciprocal_lattice == si.lattice.reciprocal_lattice

        kptbounds = si.calc_kptbounds()
        ksamp = si.calc_ksampling(nksmall=10)

        shiftk = [[ 0.5,  0.5,  0.5], [ 0.5,  0. ,  0. ], [ 0. ,  0.5,  0. ], [ 0. ,  0. ,  0.5]]
        self.assert_equal(si.calc_ngkpt(nksmall=2), [2, 2, 2])
        self.assert_equal(si.calc_shiftk(), shiftk)
        self.assert_equal(ksamp.ngkpt, [10, 10, 10])
        self.assert_equal(ksamp.shiftk, shiftk)

        si = Structure.from_mpid("mp-149")
        assert si.formula == "Si2"

        # Test abiget_spginfo
        d = si.abiget_spginfo(tolsym=None, pre="abi_")
        assert d["abi_spg_symbol"] == "Fd-3m"
        assert d["abi_spg_number"] == 227
        assert d["abi_bravais"] == "Bravais cF (face-center cubic)"

        llzo = Structure.from_file(abidata.cif_file("LLZO_oxi.cif"))
        assert llzo.is_ordered
        d = llzo.abiget_spginfo(tolsym=0.001)
        assert d["spg_number"] == 142

        mgb2_cod = Structure.from_cod_id(1526507, primitive=True)
        assert mgb2_cod.formula == "Mg1 B2"
        assert mgb2_cod.spget_lattice_type() == "hexagonal"

        mgb2 = abidata.structure_from_ucell("MgB2")
        if self.has_ase():
            mgb2.abi_primitive()

        assert [site.species_string for site in mgb2.get_sorted_structure_z()] == ["B", "B", "Mg"]

        s2inds = mgb2.get_symbol2indices()
        self.assert_equal(s2inds["Mg"], [0])
        self.assert_equal(s2inds["B"], [1, 2])

        s2coords = mgb2.get_symbol2coords()
        self.assert_equal(s2coords["Mg"], [[0, 0, 0]])
        self.assert_equal(s2coords["B"],  [[1/3, 2/3, 0.5], [2/3, 1/3, 0.5]])

        # TODO: This part should be tested more carefully
        mgb2.abi_sanitize()
        mgb2.abi_sanitize(primitive_standard=True)
        mgb2.get_conventional_standard_structure()
        assert len(mgb2.abi_string)
        assert len(mgb2.spget_summary(verbose=10))
        #print(structure._repr_html_())

        self.serialize_with_pickle(mgb2)

        pseudos = abidata.pseudos("12mg.pspnc", "5b.pspnc")
        nv = mgb2.num_valence_electrons(pseudos)
        assert nv == 8 and isinstance(nv , int)
        assert mgb2.valence_electrons_per_atom(pseudos) == [2, 3, 3]
        self.assert_equal(mgb2.calc_shiftk() , [[0.0, 0.0, 0.5]])

        bmol = Structure.boxed_molecule(pseudos, cart_coords=[[0, 0, 0], [5, 5, 5]], acell=[10, 10, 10])
        self.assert_almost_equal(bmol.volume, (10 * bohr_to_ang) ** 3)

        # FIXME This is buggy
        #acell = np.array([10, 20, 30])
        #batom = Structure.boxed_atom(abidata.pseudo("12mg.pspnc"), cart_coords=[1, 2, 3], acell=acell)
        #assert isinstance(batom, Structure)
        #assert len(batom.cart_coords) == 1
        #self.assert_equal(batom.cart_coords[0], [1, 2, 3])

        # Function to compute cubic a0 from primitive v0 (depends on struct_type)
        vol2a = {"fcc": lambda vol: (4 * vol) ** (1/3.),
                 "bcc": lambda vol: (2 * vol) ** (1/3.),
                 "zincblende": lambda vol: (4 * vol) ** (1/3.),
                 "rocksalt": lambda vol: (4 * vol) ** (1/3.),
                 "ABO3": lambda vol: vol ** (1/3.),
                 "hH": lambda vol: (4 * vol) ** (1/3.),
                 }

        a = 10
        bcc_prim = Structure.bcc(a, ["Si"], primitive=True)
        assert len(bcc_prim) == 1
        self.assert_almost_equal(a, vol2a["bcc"](bcc_prim.volume))
        bcc_conv = Structure.bcc(a, ["Si"], primitive=False)
        assert len(bcc_conv) == 2
        self.assert_almost_equal(a**3, bcc_conv.volume)
        fcc_prim = Structure.fcc(a, ["Si"], primitive=True)
        assert len(fcc_prim) == 1
        self.assert_almost_equal(a, vol2a["fcc"](fcc_prim.volume))
        fcc_conv = Structure.fcc(a, ["Si"], primitive=False)
        assert len(fcc_conv) == 4
        self.assert_almost_equal(a**3, fcc_conv.volume)
        zns = Structure.zincblende(a / bohr_to_ang, ["Zn", "S"], units="bohr")
        self.assert_almost_equal(a, vol2a["zincblende"](zns.volume))
        rock = Structure.rocksalt(a, ["Na", "Cl"])
        assert len(rock) == 2
        self.assert_almost_equal(a, vol2a["rocksalt"](rock.volume))
        perov = Structure.ABO3(a, ["Ca", "Ti", "O", "O", "O"])
        assert len(perov) == 5
        self.assert_almost_equal(a**3, perov.volume)

        # Test notebook generation.
        if self.has_nbformat():
            assert mgb2.write_notebook(nbpath=self.get_tmpname(text=True))
예제 #4
0
파일: abistruct.py 프로젝트: gmatteo/abipy
def main():

    def show_examples_and_exit(err_msg=None, error_code=1):
        """Display the usage of the script."""
        sys.stderr.write(get_epilog())
        if err_msg: sys.stderr.write("Fatal Error\n" + err_msg + "\n")
        sys.exit(error_code)

    parser = get_parser(with_epilog=True)

    # Parse command line.
    try:
        options = parser.parse_args()
    except Exception as exc:
        show_examples_and_exit(error_code=1)

    if not options.command:
        show_examples_and_exit(error_code=1)

    # loglevel is bound to the string value obtained from the command line argument.
    # Convert to upper case to allow the user to specify --loglevel=DEBUG or --loglevel=debug
    import logging
    numeric_level = getattr(logging, options.loglevel.upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError('Invalid log level: %s' % options.loglevel)
    logging.basicConfig(level=numeric_level)

    if options.verbose > 2:
        print(options)

    if options.command == "spglib":
        structure = abilab.Structure.from_file(options.filepath)
        print(structure.spget_summary(symprec=options.symprec, angle_tolerance=options.angle_tolerance,
                                      verbose=options.verbose))
        #remove_equivalent_atoms(structure)

    elif options.command == "abispg":
        structure = abilab.Structure.from_file(options.filepath)
        check_ordered_structure(structure)
        spgrp = structure.abi_spacegroup

        if spgrp is not None:
            print(structure.spget_summary(verbose=options.verbose))
        else:
            # Here we compare Abinit wrt spglib. If spgrp is None, we create a temporary
            # task to run the code in dry-run mode.
            print("FILE does not contain Abinit symmetry operations.")
            print("Calling Abinit in --dry-run mode with chkprim = 0 to get space group.")
            from abipy.data.hgh_pseudos import HGH_TABLE
            gsinp = factories.gs_input(structure, HGH_TABLE, spin_mode="unpolarized")
            gsinp["chkprim"] = 0
            abistructure = gsinp.abiget_spacegroup(tolsym=options.tolsym)
            print(abistructure.spget_summary(verbose=options.verbose))

            diff_structures([structure, abistructure], mode=options.diff_mode,
                            headers=["Input structure", "After Abinit symmetrization"], fmt="abivars")

            # Save file.
            save_structure(abistructure, options)

    elif options.command == "convert":
        fmt = options.format
        if fmt == "cif" and options.filepath.endswith(".cif"): fmt = "abivars"
        print(abilab.Structure.from_file(options.filepath).convert(fmt=fmt))

    elif options.command == "supercell":
        structure = abilab.Structure.from_file(options.filepath)

        options.scaling_matrix = np.array(options.scaling_matrix)
        if len(options.scaling_matrix) == 9:
            options.scaling_matrix.shape = (3, 3)
        if options.verbose:
            print("scaling matrix: ", options.scaling_matrix)

        supcell = structure * options.scaling_matrix
        #supcell = structure.make_supercell(scaling_matrix, to_unit_cell=True)
        print(supcell.convert(fmt=options.format))

    elif options.command == "abisanitize":
        print("\nCalling abi_sanitize to get a new structure in which:")
        print("    * Structure is refined.")
        print("    * Reduced to primitive settings.")
        print("    * Lattice vectors are exchanged if the triple product is negative\n")

        structure = abilab.Structure.from_file(options.filepath)
        sanitized = structure.abi_sanitize(symprec=options.symprec, angle_tolerance=options.angle_tolerance,
                                           primitive=not options.no_primitive, primitive_standard=options.primitive_standard)
        index = [options.filepath, "abisanitized"]
        dfs = abilab.dataframes_from_structures([structure, sanitized], index=index, with_spglib=True)

        abilab.print_dataframe(dfs.lattice, title="Lattice parameters:")
        abilab.print_dataframe(dfs.coords, title="Atomic positions (columns give the site index):")

        if not options.verbose:
            print("\nUse -v for more info")
            #print(sanitized.convert(fmt="cif"))
        else:
            #print("\nDifference between structures:")
            if len(structure) == len(sanitized):
                table = []
                for line1, line2 in zip(str(structure).splitlines(), str(sanitized).splitlines()):
                    table.append([line1, line2])
                print(str(tabulate(table, headers=["Initial structure", "Abisanitized"])))

            else:
                print("\nInitial structure:")
                print(structure)
                print("\nabisanitized structure:")
                print(sanitized)

        # Save file.
        save_structure(sanitized, options)

    elif options.command == "irefine":
        structure = abilab.Structure.from_file(options.filepath)
        sanitized = structure.copy()
        symprec, angle_tolerance = options.symprec, options.angle_tolerance
        print("Calling abi_sanitize with increasing tolerances to reach target space group:", options.target_spgnum)
        print("Using symprec_step: ", options.symprec_step, ", angle_tolerance_step:", options.angle_tolerance_step,
              "ntrial", options.ntrial)
        itrial = 0
        while itrial < options.ntrial:
            print(">>> Trying with symprec: %s, angle_tolerance: %s" % (symprec, angle_tolerance))
            sanitized = sanitized.abi_sanitize(symprec=symprec, angle_tolerance=angle_tolerance,
                primitive=not options.no_primitive, primitive_standard=options.primitive_standard)
            spg_symb, spg_num = sanitized.get_space_group_info(symprec=symprec, angle_tolerance=angle_tolerance)
            print(">>> Space-group number:", spg_symb, ", symbol:", spg_num, "for trial:", itrial)
            if spg_num == options.target_spgnum:
                print(2 * "\n", "# Final structure with space group number:", spg_symb, ", symbol:", spg_num, 2 *"\n")
                print(sanitized.convert(fmt="cif"))
                break

            # Increment counter and tols.
            itrial += 1
            symprec += options.symprec_step
            angle_tolerance += options.angle_tolerance_step
        else:
            print("Cannot find space group number:", options.target_spgnum, "after", options.ntrial, "iterations")
            return 1

        # Save file.
        #save_structure(sanitized, options)

    elif options.command == "conventional":
        print("\nCalling get_conventional_standard_structure to get conventional structure:")
        print("The standards are defined in Setyawan, W., & Curtarolo, S. (2010). ")
        print("High-throughput electronic band structure calculations: Challenges and tools. ")
        print("Computational Materials Science, 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010\n")

        structure = abilab.Structure.from_file(options.filepath)
        conv = structure.get_conventional_standard_structure(international_monoclinic=True,
                                           symprec=options.symprec, angle_tolerance=options.angle_tolerance)
        index = [options.filepath, "conventional"]
        dfs = abilab.dataframes_from_structures([structure, conv], index=index, with_spglib=True)

        abilab.print_dataframe(dfs.lattice, title="Lattice parameters:")
        if options.verbose:
            abilab.print_dataframe(dfs.coords, title="Atomic positions (columns give the site index):")

        if not options.verbose:
            print("\nUse -v for more info")
        else:
            #print("\nDifference between structures:")
            if len(structure) == len(conv):
                table = []
                for line1, line2 in zip(str(structure).splitlines(), str(conv).splitlines()):
                    table.append([line1, line2])
                print(str(tabulate(table, headers=["Initial structure", "Conventional"])))

            else:
                print("\nInitial structure:\n", structure)
                print("\nConventional structure:\n", conv)

        # Save file.
        save_structure(conv, options)

    elif options.command == "neighbors":
        abilab.Structure.from_file(options.filepath).print_neighbors(radius=options.radius)

    elif options.command == "interpolate":
        initial_structure = abilab.Structure.from_file(options.filepaths[0])
        end_structure = abilab.Structure.from_file(options.filepaths[1])
        structures = initial_structure.interpolate(end_structure, nimages=options.nimages,
                                                   interpolate_lattices=False, pbc=True,
                                                   autosort_tol=options.autosort_tol)
        structures = list(map(abilab.Structure.as_structure, structures))
        for i, s in enumerate(structures):
            print(marquee("Structure #%d" % i, mark="="))
            print(s.convert(fmt=options.format))
            print(" ")

    elif options.command == "xrd":
        structure = abilab.Structure.from_file(options.filepath)
        two_theta_range = tuple(float(t) for t in options.two_theta_range)
        structure.plot_xrd(wavelength=options.wavelength, two_theta_range=two_theta_range,
                           symprec=options.symprec, annotate_peaks=not options.no_annotate_peaks)

    elif options.command == "oxistate":
        print(abilab.Structure.from_file(options.filepath).get_oxi_state_decorated())

    elif options.command == "ipython":
        structure = abilab.Structure.from_file(options.filepath)
        print("Invoking Ipython, `structure` object will be available in the Ipython terminal")
        import IPython
        IPython.start_ipython(argv=[], user_ns={"structure": structure})

    elif options.command == "notebook":
        structure = abilab.Structure.from_file(options.filepath)
        structure.make_and_open_notebook(nbpath=None, foreground=options.foreground)

    elif options.command == "visualize":
        structure = abilab.Structure.from_file(options.filepath)
        print(structure)
        print("Visualizing structure with:", options.appname)
        structure.visualize(appname=options.appname)

    elif options.command == "kpath":
        structure = abilab.Structure.from_file(options.filepath)
        print(structure.get_kpath_input_string(fmt=options.format, line_density=10))

    elif options.command == "bz":
        abilab.Structure.from_file(options.filepath).plot_bz()

    elif options.command == "ngkpt":
        d = abilab.Structure.from_file(options.filepath).calc_ksampling(options.nksmall)
        print("ngkpt %d %d %d" % (d.ngkpt[0], d.ngkpt[1], d.ngkpt[2]))
        print("nshiftk ", len(d.shiftk), "\nshiftk")
        for s in d.shiftk:
            print("  %s %s %s" % (s[0], s[1], s[2]))

    elif options.command == "ktables":
        structure = abilab.Structure.from_file(options.filepath)
        k = Ktables(structure, options.mesh, options.is_shift, not options.no_time_reversal)
        print(k)
        print("")
        print("NB: These results are obtained by calling spglib with the structure read from file.")
        print("The k-points might differ from the ones expected by Abinit, especially if the space groups differ.")

        if not options.verbose:
            print("\nUse -v to obtain the BZ --> IBZ mapping.")
        else:
            print()
            k.print_bz2ibz()

    elif options.command == "abikmesh":
        structure = abilab.Structure.from_file(options.filepath)
        if options.kppa is None and options.ngkpt is None:
            raise ValueError("Either ngkpt or kppa must be provided")

        if options.kppa is not None:
            print("Calling Abinit to compute the IBZ with kppa:", options.kppa, "and shiftk:", options.shiftk)
            ibz = IrredZone.from_kppa(structure, options.kppa, options.shiftk,
                                      kptopt=options.kptopt, verbose=options.verbose)
        else:
            print("Calling Abinit to compute the IBZ with ngkpt:", options.ngkpt, "and shiftk:", options.shiftk)
            ibz = IrredZone.from_ngkpt(structure, options.ngkpt, options.shiftk,
                                       kptopt=options.kptopt, verbose=options.verbose)

        print(ibz.to_string(verbose=options.verbose))

    #elif options.command == "kmesh_jhu":
    #    structure = abilab.Structure.from_file(options.filepath)
    #    ksampling = structure.ksampling_from_jhudb(kppra=1000)
    #    #print(ksampling)

    elif options.command == "lgk":
        structure = abilab.Structure.from_file(options.filepath)
        spgrp = structure.abi_spacegroup
        if spgrp is None:
            cprint("Your file does not contain Abinit symmetry operations.", "yellow")
            cprint("Will call spglib to obtain the space group (assuming time-reversal: %s)" %
                   (not options.no_time_reversal), "yellow")
            spgrp = AbinitSpaceGroup.from_structure(structure, has_timerev=not options.no_time_reversal,
                        symprec=options.symprec, angle_tolerance=options.angle_tolerance)
        print()
        print(marquee("Structure", mark="="))
        print(structure.spget_summary(verbose=options.verbose))
        print("\n")

        print(marquee("Little Group", mark="="))
        ltk = spgrp.find_little_group(kpoint=options.kpoint)
        print(ltk.to_string(verbose=options.verbose))

    elif options.command == "kstar":
        structure = abilab.Structure.from_file(options.filepath)

        # Call spglib to get spacegroup if Abinit spacegroup is not available.
        if structure.abi_spacegroup is None:
            structure.spgset_abi_spacegroup(has_timerev=not options.no_time_reversal)

        kpoint = Kpoint(options.kpoint, structure.reciprocal_lattice)
        kstar = kpoint.compute_star(structure.abi_spacegroup, wrap_tows=True)
        print("Found %s points in the star of %s\n" % (len(kstar), repr(kpoint)))
        for k in kstar:
            print(4 * " ", repr(k))

    elif options.command == "keq":
        structure = abilab.Structure.from_file(options.filepath)

        # Call spglib to get spacegroup if Abinit spacegroup is not available.
        if structure.abi_spacegroup is None:
            structure.spgset_abi_spacegroup(has_timerev=not options.no_time_reversal)

        k1, k2 = options.kpoints[:3], options.kpoints[3:6]
        k1tab = structure.abi_spacegroup.symeq(k1, k2)

        if k1tab.isym != -1:
            print("\nk1:", k1, "and k2:", k2, "are symmetry equivalent k-points\n")
            print("Related by the symmetry operation (reduced coords):\n", k1tab.op)
            print("With umklapp vector Go = TO(k1) - k2 =", k1tab.g0)
        else:
            print(k1, "and", k2, "are NOT symmetry equivalent")

    elif options.command == "mp_id":
        # Get the Structure corresponding to material_id.
        structure = abilab.Structure.from_mpid(options.mpid, final=True,
                                               api_key=options.mapi_key, endpoint=options.endpoint)
        # Convert to format and print it.
        print(structure.convert(fmt=options.format))

    elif options.command == "mp_match":
        mp = abilab.mp_match_structure(options.filepath)
        if not mp.structures:
            cprint("No structure found in database", "yellow")
            return 1

        if options.notebook:
            return mp.make_and_open_notebook(foreground=options.foreground)
        else:
            mp.print_results(fmt=options.format, verbose=options.verbose)

        if options.browser:
            mp.open_browser(limit=None if options.verbose == 2 else 10)

    elif options.command == "mp_search":
        mp = abilab.mp_search(options.chemsys_formula_id)
        if not mp.structures:
            cprint("No structure found in Materials Project database", "yellow")
            return 1
        if options.select_spgnum: mp = mp.filter_by_spgnum(options.select_spgnum)

        if options.notebook:
            return mp.make_and_open_notebook(foreground=options.foreground)
        else:
            mp.print_results(fmt=options.format, verbose=options.verbose)

        if options.browser:
            mp.open_browser(limit=None if options.verbose == 2 else 10)

    elif options.command == "mp_pd":
        if os.path.exists(options.file_or_elements):
            structure = abilab.Structure.from_file(options.file_or_elements)
            elements = structure.symbol_set
        else:
            elements = options.file_or_elements.split("-")

        if options.verbose > 1: print("Building phase-diagram for elements:", elements)
        with abilab.restapi.get_mprester(api_key=options.mapi_key, endpoint=options.endpoint) as rest:
            pdr = rest.get_phasediagram_results(elements)
            pdr.print_dataframes(verbose=options.verbose)
            pdr.plot(show_unstable=options.show_unstable)

    elif options.command == "cod_search":
        cod = abilab.cod_search(options.formula, primitive=options.primitive)
        if not cod.structures:
            cprint("No structure found in COD database", "yellow")
            return 1
        if options.select_spgnum: cod = cod.filter_by_spgnum(options.select_spgnum)

        if options.notebook:
            return cod.make_and_open_notebook(foreground=options.foreground)
        else:
            cod.print_results(fmt=options.format, verbose=options.verbose)

    elif options.command == "cod_id":
        # Get the Structure from COD
        structure = abilab.Structure.from_cod_id(options.cod_identifier, primitive=options.primitive)
        # Convert to format and print it.
        print(structure.convert(fmt=options.format))

    elif options.command == "animate":
        filepath = options.filepath
        if any(filepath.endswith(ext) for ext in ("HIST", "HIST.nc")):
            with abilab.abiopen(filepath) as hist:
                structures = hist.structures

        elif "XDATCAR" in filepath:
            structures = Xdatcar(filepath).structures
            if not structures:
                raise RuntimeError("Your Xdatcar contains only one structure. Due to a bug "
                    "in the pymatgen routine, your structures won't be parsed correctly"
                    "Solution: Add another structure at the end of the file.")
        else:
            raise ValueError("Don't know how to handle file %s" % filepath)

        xsf_write_structure(sys.stdout, structures)

    else:
        raise ValueError("Unsupported command: %s" % options.command)

    return 0