Exemple #1
0
    def test_kpoint_algebra(self):
        """Test k-point algebra."""
        lattice = self.lattice
        gamma = Kpoint([0, 0, 0], lattice)
        pgamma = Kpoint([1, 0, 1], lattice)
        X = Kpoint([0.5, 0, 0], lattice)
        K = Kpoint([1/3, 1/3, 1/3], lattice)
        print(X)

        self.serialize_with_pickle(X, protocols=[-1])

        self.assert_almost_equal(X.versor().norm, 1.0)

        self.assertTrue(X[0] == 0.5)
        self.assertListEqual(pgamma[:2].tolist(), [1,0])

        self.assertEqual(gamma, pgamma)
        self.assertEqual(gamma + pgamma, gamma)
        self.assertEqual(pgamma + X, X)
        self.assertNotEqual(gamma, X)

        self.assertEqual(X.norm, (gamma + X).norm)

        self.assertEqual(X.norm, (gamma + X).norm)
        self.assertEqual(X.norm, np.sqrt(np.sum(X.cart_coords**2)))

        self.assertTrue(hash(gamma) == hash(pgamma))

        if hash(K) != hash(X):
            self.assertTrue(K != X)

        # test ob_border
        self.assertFalse(gamma.on_border)
        self.assertTrue(X.on_border)
        self.assertFalse(K.on_border)
Exemple #2
0
    def pwwtows_inplace(self):
        """Wrap the kpoint to the interval ]-1/2,1/2] and update pwwave accordingly."""
        kpoint = Kpoint(self.gsphere.kpoint, self.gsphere.gprimd)
        wkpt = kpoint.wrap_to_ws()

        if np.allclose(wkpt.rcoord, kpoint.rcoord):
            return

        #@David FIXME this is wrong
        gvector = np.array(kpoint.rcoord - wkpt.rcoord, np.int)
        self.gsphere.gvecs = self.gsphere.gvecs + gvector
        self.gsphere.kpoint = wkpt.rcoord
Exemple #3
0
    def test_askpoints(self):
        """Test askpoints."""
        lattice = self.lattice
        kpts = as_kpoints([1, 2, 3], lattice)

        self.serialize_with_pickle(kpts, protocols=[-1])

        newkpts = as_kpoints(kpts, lattice)
        self.assertTrue(kpts is newkpts)

        kpts = as_kpoints([1, 2, 3, 4, 5, 6], lattice)
        self.assertTrue(len(kpts) == 2)
        self.assertTrue(kpts[0] == Kpoint([1, 2, 3], lattice))
        self.assertTrue(kpts[1] == Kpoint([4, 5, 6], lattice))
Exemple #4
0
    def __init__(self, ecut, lattice, kpoint, gvecs, istwfk=1):
        """
        Args:
            ecut:
                Cutoff energy in Hartree.
            lattice:
                Reciprocal lattice.
            kpoint:
                Reduced coordinates of the k-point.
            gvecs:
                Array with the reduced coordinates of the G-vectors.
            istwfk:
                Storage option (time-reversal symmetry, see abinit variable)
        """
        self.ecut = ecut
        self.lattice = lattice
        self.kpoint = Kpoint.askpoint(kpoint, lattice)

        self._gvecs = np.reshape(np.array(gvecs), (-1, 3))
        self.npw = self.gvecs.shape[0]

        self.istwfk = istwfk

        if istwfk != 1:
            raise NotImplementedError("istwfk %d is not implemented" % self.istwfk)
Exemple #5
0
    def _find_iqpt_qpoint(self, qpoint):
        if duck.is_intlike(qpoint):
            iq = qpoint
            qpoint = self.qpoints[iq]
        else:
            qpoint = Kpoint.as_kpoint(qpoint, self.structure.reciprocal_lattice)
            iq = self.qpoints.index(qpoint)

        return iq, qpoint
Exemple #6
0
 def from_dict(cls, d):
     ovl_from_dict = cls(d['_wfk_files'],
                         rspace_translations=d['_rspace_trans']['real'])
     for k, v in d.items():
         if k == '_wfk_files' or k == '_rspace_trans':
             continue
         kpt0 = Kpoint(v['kpt0']['frac_coords'],
                       pmg.Lattice.from_dict(
                           v['kpt0']['reciprocal_lattice']),
                       weight=v['kpt0']['weight'],
                       name=v['kpt0']['name'])
         kpt1 = Kpoint(v['kpt1']['frac_coords'],
                       pmg.Lattice.from_dict(
                           v['kpt1']['reciprocal_lattice']),
                       weight=v['kpt1']['weight'],
                       name=v['kpt1']['name'])
         ovl_from_dict[((v['wfk0'], kpt0), (v['wfk1'], kpt1))] = np.array(
             v['val']['real'], dtype=complex) + 1.j * np.array(
                 v['val']['imag'], dtype=complex)
     return ovl_from_dict
Exemple #7
0
 def __init__(self, qpoint, freq, displ_cart, structure):
     """
     Args:
         qpoint: qpoint in reduced coordinates.
         freq: Phonon frequency in eV.
         displ: Displacement (Cartesian coordinates, Angstrom)
         structure: :class:`Structure` object.
     """
     self.qpoint = Kpoint.as_kpoint(qpoint, structure.reciprocal_lattice)
     self.freq = freq
     self.displ_cart = displ_cart
     self.structure = structure
Exemple #8
0
 def __init__(self, qpoint, freq, displ_cart, structure):
     """
     Args:
         qpoint: qpoint in reduced coordinates.
         freq: Phonon frequency in eV.
         displ: Displacement (Cartesian coordinates, Angstrom)
         structure: :class:`Structure` object.
     """
     self.qpoint = Kpoint.as_kpoint(qpoint, structure.reciprocal_lattice)
     self.freq = freq
     self.displ_cart = displ_cart
     self.structure = structure
Exemple #9
0
def pww_translation_inplace(self, gvector, rprimd=None):
    """Translates the pwwave from 1 kpoint by one gvector."""
    if rprimd is None:
        rprimd = self.structure.lattice.matrix
    # self.gsphere.kpoint = self.gsphere.kpoint + gvector
    self.gsphere.kpoint = self.gsphere.kpoint + Kpoint(
        gvector, self.gsphere.kpoint.lattice)
    # self.gsphere.gvecs = self.gsphere.gvecs + gvector
    self.gsphere._gvecs = self.gsphere.gvecs - gvector
    # fft_ndivs = (self.mesh.shape[0] + 2, self.mesh.shape[1] + 2, self.mesh.shape[2] + 2)
    # newmesh = Mesh3D(fft_ndivs, rprimd, pbc=True)
    # self.mesh = newmesh
    self.delete_ur()  # ur will get recomputed correctly as needed
Exemple #10
0
    def test_kpointlist(self):
        """Test KpointList."""
        lattice = self.lattice

        frac_coords = [0, 0, 0, 1 / 2, 1 / 2, 1 / 2, 1 / 3, 1 / 3, 1 / 3]
        weights = [0.1, 0.2, 0.7]

        klist = KpointList(lattice, frac_coords, weights=weights)

        self.serialize_with_pickle(klist, protocols=[-1])
        self.assertMSONable(klist, test_if_subclass=False)

        assert klist.sum_weights() == 1
        assert len(klist) == 3

        for i, kpoint in enumerate(klist):
            assert kpoint in klist
            assert klist.count(kpoint) == 1
            assert klist.find(kpoint) == i

        # Changing the weight of the Kpoint object should change the weights of klist.
        for kpoint in klist:
            kpoint.set_weight(1.0)
        assert np.all(klist.weights == 1.0)

        # Test find_closest
        iclose, kclose, dist = klist.find_closest([0, 0, 0])
        assert iclose == 0 and dist == 0.

        iclose, kclose, dist = klist.find_closest(
            Kpoint([0.001, 0.002, 0.003], klist.reciprocal_lattice))
        assert iclose == 0
        self.assert_almost_equal(dist, 0.001984943324127921)

        frac_coords = [0, 0, 0, 1 / 2, 1 / 3, 1 / 3]
        other_klist = KpointList(lattice, frac_coords)

        # Test __add__
        add_klist = klist + other_klist

        for k in itertools.chain(klist, other_klist):
            assert k in add_klist

        assert add_klist.count([0, 0, 0]) == 2

        # Remove duplicated k-points.
        add_klist = add_klist.remove_duplicated()
        self.assertTrue(add_klist.count([0, 0, 0]) == 1)
        self.assertTrue(len(add_klist) == 4)
        self.assertTrue(add_klist == add_klist.remove_duplicated())
Exemple #11
0
    def _make_ticks_and_labels(self, qlabels):
        """Return ticks and labels from the mapping {qred: qstring} given in qlabels."""
        if qlabels is not None:
            d = OrderedDict()

            for qcoord, qname in qlabels.items():
                # Build Kpoint instancee
                qtick = Kpoint(qcoord, self.structure.reciprocal_lattice)
                for q, qpoint in enumerate(self.qpoints):
                    if qtick == qpoint:
                        d[q] = qname
        else:
            d = self._auto_qlabels

        # Return ticks, labels
        return list(d.keys()), list(d.values())
Exemple #12
0
def get_strings(kpoints, direction):
    """ given a list of Kpoints and a direction x, y, z
        return a list of strings of kpoints along the corresponding direction """
    # includes the extra kpoint shifted by a gvector
    # adapted from some very old code, super inefficient, should clean up
    # but it's also pretty much never a bottleneck

    comps, dir_comp, gvec = direction_to_vals(direction)
    bz_2d_set = sorted(
        set([tuple((kpt.frac_coords[i] for i in comps)) for kpt in kpoints]))
    strings = []
    for bz_2d_pt in bz_2d_set:
        this_string = []
        for kpt in kpoints:
            in_this_string = (
                (abs(kpt.frac_coords[comps[0]] - bz_2d_pt[0]) < 1.e-5)
                and (abs(kpt.frac_coords[comps[1]] - bz_2d_pt[1]) < 1.e-5))
            if in_this_string:
                this_string.append(kpt)
        this_string.sort(key=lambda k: k.frac_coords[dir_comp])
        this_string.append(this_string[0] +
                           Kpoint(gvec, kpoints.reciprocal_lattice))
        strings.append(this_string)
    return strings
Exemple #13
0
    def test_kpoint_algebra(self):
        """Test k-point algebra."""
        lattice = self.lattice
        gamma = Kpoint([0, 0, 0], lattice)
        pgamma = Kpoint([1, 0, 1], lattice)
        X = Kpoint([0.5, 0, 0], lattice)
        K = Kpoint([1 / 3, 1 / 3, 1 / 3], lattice)
        print(X)

        # TODO
        #assert np.all(np.array(X) == X.frac_coords)

        self.serialize_with_pickle(X, protocols=[-1])
        self.assert_almost_equal(X.versor().norm, 1.0)

        self.assertTrue(X[0] == 0.5)
        self.assertListEqual(pgamma[:2].tolist(), [1, 0])

        self.assertEqual(gamma, pgamma)
        self.assertEqual(gamma + pgamma, gamma)
        self.assertEqual(pgamma + X, X)
        self.assertNotEqual(gamma, X)

        self.assertEqual(X.norm, (gamma + X).norm)

        self.assertEqual(X.norm, (gamma + X).norm)
        self.assertEqual(X.norm, np.sqrt(np.sum(X.cart_coords**2)))

        self.assertTrue(hash(gamma) == hash(pgamma))

        if hash(K) != hash(X):
            self.assertTrue(K != X)

        # test on_border
        self.assertFalse(gamma.on_border)
        self.assertTrue(X.on_border)
        self.assertFalse(K.on_border)
Exemple #14
0
    def test_kpoint_algebra(self):
        """Test k-point algebra."""
        lattice = self.lattice
        gamma = Kpoint([0, 0, 0], lattice)
        pgamma = Kpoint([1, 0, 1], lattice)
        X = Kpoint([0.5, 0, 0], lattice)
        K = Kpoint([1 / 3, 1 / 3, 1 / 3], lattice)
        repr(X)
        str(X)
        assert X.to_string(verbose=2)

        assert gamma.is_gamma()
        assert not pgamma.is_gamma()
        assert pgamma.is_gamma(allow_umklapp=True)
        assert not X.is_gamma()

        # TODO
        #assert np.all(np.array(X) == X.frac_coords)

        self.serialize_with_pickle(X, protocols=[-1])
        self.assert_almost_equal(X.versor().norm, 1.0)

        other_gamma = Kpoint.gamma(lattice, weight=1)
        assert other_gamma == [0, 0, 0]
        assert other_gamma == gamma
        assert gamma.versor() == gamma

        X_outside = Kpoint([1.5, 0, 0], lattice)
        assert X_outside.wrap_to_ws() == X
        assert X_outside.wrap_to_ws() == [0.5, 0, 0]

        X_outside = Kpoint([0.7, 0, 0], lattice)
        assert X_outside.wrap_to_bz() == [-0.3, 0, 0]

        assert X[0] == 0.5
        self.assert_equal(pgamma[:2].tolist(), [1, 0])

        assert gamma == pgamma
        assert gamma + pgamma == gamma
        assert pgamma + X == X
        assert gamma != X
        # TODO
        #assert gamma != 0

        assert X.norm == (gamma + X).norm
        assert X.norm == (gamma + X).norm
        assert X.norm == np.sqrt(np.sum(X.cart_coords**2))
        # TODO
        #assert X != 0.5

        assert hash(gamma) == hash(pgamma)
        if hash(K) != hash(X):
            assert K != X

        # test on_border
        assert not gamma.on_border
        assert X.on_border
        assert not K.on_border
Exemple #15
0
    def test_kpointlist(self):
        """Test KpointList."""
        lattice = self.lattice

        frac_coords = [0, 0, 0, 1 / 2, 1 / 2, 1 / 2, 1 / 3, 1 / 3, 1 / 3]
        weights = [0.1, 0.2, 0.7]

        klist = KpointList(lattice, frac_coords, weights=weights)
        repr(klist)
        str(klist)

        self.serialize_with_pickle(klist, protocols=[-1])
        self.assertMSONable(klist, test_if_subclass=False)

        self.assert_equal(klist.frac_coords.flatten(), frac_coords)
        self.assert_equal(klist.get_cart_coords(),
                          np.reshape([k.cart_coords for k in klist], (-1, 3)))
        assert klist.sum_weights() == 1
        assert len(klist) == 3

        for i, kpoint in enumerate(klist):
            assert kpoint in klist
            assert klist.count(kpoint) == 1
            assert klist.find(kpoint) == i

        # Changing the weight of the Kpoint object should change the weights of klist.
        for kpoint in klist:
            kpoint.set_weight(1.0)
        assert np.all(klist.weights == 1.0)

        # Test find_closest
        iclose, kclose, dist = klist.find_closest([0, 0, 0])
        assert iclose == 0 and dist == 0.

        iclose, kclose, dist = klist.find_closest(
            Kpoint([0.001, 0.002, 0.003], klist.reciprocal_lattice))
        assert iclose == 0
        self.assert_almost_equal(dist, 0.001984943324127921)

        # Compute mapping k_index --> (k + q)_index, g0
        k2kqg = klist.get_k2kqg_map((0, 0, 0))
        assert all(ikq == ik for ik, (ikq, g0) in k2kqg.items())
        k2kqg = klist.get_k2kqg_map((1 / 2, 1 / 2, 1 / 2))
        assert len(k2kqg) == 2
        assert k2kqg[0][0] == 1 and np.all(k2kqg[0][1] == 0)
        assert k2kqg[1][0] == 0 and np.all(k2kqg[1][1] == 1)

        frac_coords = [0, 0, 0, 1 / 2, 1 / 3, 1 / 3]
        other_klist = KpointList(lattice, frac_coords)

        # Test __add__
        add_klist = klist + other_klist

        for k in itertools.chain(klist, other_klist):
            assert k in add_klist

        assert add_klist.count([0, 0, 0]) == 2

        # Remove duplicated k-points.
        add_klist = add_klist.remove_duplicated()
        assert add_klist.count([0, 0, 0]) == 1
        assert len(add_klist) == 4
        assert add_klist == add_klist.remove_duplicated()
Exemple #16
0
    def test_kpoint_algebra(self):
        """Test k-point algebra."""
        lattice = self.lattice
        gamma = Kpoint([0, 0, 0], lattice)
        pgamma = Kpoint([1, 0, 1], lattice)
        X = Kpoint([0.5, 0, 0], lattice)
        K = Kpoint([1/3, 1/3, 1/3], lattice)
        repr(X); str(X)
        assert X.to_string(verbose=2)

        assert gamma.is_gamma()
        assert not pgamma.is_gamma()
        assert pgamma.is_gamma(allow_umklapp=True)
        assert not X.is_gamma()

        # TODO
        #assert np.all(np.array(X) == X.frac_coords)

        self.serialize_with_pickle(X, protocols=[-1])
        self.assert_almost_equal(X.versor().norm, 1.0)

        other_gamma = Kpoint.gamma(lattice, weight=1)
        assert other_gamma == [0, 0, 0]
        assert other_gamma == gamma
        assert gamma.versor() == gamma

        X_outside = Kpoint([1.5, 0, 0], lattice)
        assert X_outside.wrap_to_ws() == X
        assert X_outside.wrap_to_ws() == [0.5, 0, 0]

        X_outside = Kpoint([0.7, 0, 0], lattice)
        assert X_outside.wrap_to_bz() == [-0.3, 0, 0]

        assert X[0] == 0.5
        self.assert_equal(pgamma[:2].tolist(), [1,0])

        assert gamma == pgamma
        assert gamma + pgamma == gamma
        assert pgamma + X == X
        assert gamma != X
        # TODO
        #assert gamma != 0

        assert X.norm == (gamma + X).norm
        assert X.norm ==  (gamma + X).norm
        assert X.norm == np.sqrt(np.sum(X.cart_coords**2))
        # TODO
        #assert X != 0.5

        assert hash(gamma) == hash(pgamma)
        if hash(K) != hash(X):
            assert K != X

        # test on_border
        assert not gamma.on_border
        assert X.on_border
        assert not K.on_border
Exemple #17
0
 def qpoint(self):
     """Q-point object."""
     return Kpoint(self.reader.read_value('qpoint'), self.structure.reciprocal_lattice)
Exemple #18
0
    def plot_gkq2_qpath(self, band_kq, band_k, kpoint=0, with_glr=False, qdamp=None, nu_list=None, # spherical_average=False,
                        ax=None, fontsize=8, eph_wtol=EPH_WTOL, **kwargs):
        r"""
        Plot the magnitude of the electron-phonon matrix elements <k+q, band_kq| Delta_{q\nu} V |k, band_k>
        for a given set of (band_kq, band, k) as a function of the q-point.

        Args:
            band_ks: Band index of the k+q states (starts at 0)
            band_k: Band index of the k state (starts at 0)
            kpoint: |Kpoint| object or index.
            with_glr: True to plot the long-range component estimated from Verdi's model.
            qdamp:
            nu_list: List of phonons modes to be selected (starts at 0). None to select all modes.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            fontsize: Label and title fontsize.

        Return: |matplotlib-Figure|
        """
        if duck.is_intlike(kpoint):
            ik = kpoint
            kpoint = self.kpoints[ik]
        else:
            kpoint = Kpoint.as_kpoint(kpoint, self.abifiles[0].structure.reciprocal_lattice)
            ik = self.kpoints.index(kpoint)

        # Assume abifiles are already ordered according to q-path.
        xs = list(range(len(self.abifiles)))
        natom3 = len(self.abifiles[0].structure) * 3
        nsppol = self.abifiles[0].nsppol
        nqpt = len(self.abifiles)
        gkq_snuq = np.empty((nsppol, natom3, nqpt), dtype=np.complex)
        if with_glr: gkq_lr = np.empty((nsppol, natom3, nqpt), dtype=np.complex)

        # TODO: Should take into account possible degeneracies in k and kq...
        xticks, xlabels = [], []
        for iq, abifile in enumerate(self.abifiles):
            qpoint = abifile.qpoint
            #d3q_fact = one if not spherical_average else np.sqrt(4 * np.pi) * qpoint.norm

            name = qpoint.name if qpoint.name is not None else abifile.structure.findname_in_hsym_stars(qpoint)
            if qpoint.name is not None:
                xticks.append(iq)
                xlabels.append(name)

            phfreqs_ha, phdispl_red = abifile.phfreqs_ha, abifile.phdispl_red
            ncvar = abifile.reader.read_variable("gkq")
            for spin in range(nsppol):
                gkq_atm = ncvar[spin, ik, :, band_k, band_kq]
                gkq_atm = gkq_atm[:, 0] + 1j * gkq_atm[:, 1]

                # Transform the gkk matrix elements from (atom, red_direction) basis to phonon-mode basis.
                gkq_snuq[spin, :, iq] = 0.0
                for nu in range(natom3):
                    if phfreqs_ha[nu] < eph_wtol: continue
                    gkq_snuq[spin, nu, iq] = np.dot(phdispl_red[nu], gkq_atm) / np.sqrt(2.0 * phfreqs_ha[nu])

            if with_glr:
                # Compute long range part with (simplified) generalized Frohlich model.
                gkq_lr[spin, :, iq] = glr_frohlich(qpoint, abifile.becs_cart, abifile.epsinf_cart,
                                                   abifile.phdispl_cart_bohr, phfreqs_ha, abifile.structure, qdamp=qdamp)

        ax, fig, plt = get_ax_fig_plt(ax=ax)

        nu_list = list(range(natom3)) if nu_list is None else list(nu_list)
        for spin in range(nsppol):
            for nu in nu_list:
                ys = np.abs(gkq_snuq[spin, nu]) * abu.Ha_meV
                pre_label = kwargs.pop("pre_label",r"$g_{\bf q}$")
                if nsppol == 1: label = r"%s $\nu$: %s" % (pre_label, nu)
                if nsppol == 2: label = r"%s $\nu$: %s, spin: %s" % (pre_label, nu, spin)
                ax.plot(xs, ys, linestyle="--", label=label)
                if with_glr:
                    # Plot model with G = 0 and delta_nn'
                    ys = np.abs(gkq_lr[spin, nu]) * abu.Ha_meV
                    label = r"$g_{\bf q}^{\mathrm{lr0}}$ $\nu$: %s" % nu
                    ax.plot(xs, ys, linestyle="", marker="o", label=label)

        ax.grid(True)
        ax.set_xlabel("Wave Vector")
        ax.set_ylabel(r"$|g_{\bf q}|$ (meV)")
        if xticks:
            ax.set_xticks(xticks, minor=False)
            ax.set_xticklabels(xlabels, fontdict=None, minor=False, size=kwargs.pop("klabel_size", "large"))

        ax.legend(loc="best", fontsize=fontsize, shadow=True)
        title = r"$band_{{\bf k} + {\bf q}: %s, band_{\bf{k}}: %s, kpoint: %s" % (band_kq, band_k, repr(kpoint))
        ax.set_title(title, fontsize=fontsize)

        return fig
Exemple #19
0
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
Exemple #20
0
    def test_kpath_api(self):
        """Testing Kpath API."""
        structure = abilab.Structure.as_structure(abidata.cif_file("si.cif"))

        knames = ["G", "X", "L", "G"]
        kpath = Kpath.from_names(structure, knames, line_density=5)
        repr(kpath)
        str(kpath)
        assert kpath.to_string(verbose=2, title="Kpath")
        assert not kpath.is_ibz and kpath.is_path
        assert kpath[0].is_gamma and kpath[-1].is_gamma
        #assert len(kpath.ds) == len(self) - 1
        #assert kpath.ksampling.kptopt == 1
        #self.assert_equal(kpath.ksampling.mpdivs, [4, 4, 4])

        assert Kpoint.from_name_and_structure("Gamma", structure) == kpath[0]

        assert len(kpath.ds) == len(kpath) - 1
        assert len(kpath.versors) == len(kpath) - 1
        assert len(kpath.lines) == len(knames) - 1
        self.assert_almost_equal(kpath.frac_bounds,
                                 structure.get_kcoords_from_names(knames))
        self.assert_almost_equal(
            kpath.cart_bounds,
            structure.get_kcoords_from_names(knames, cart_coords=True))

        r = kpath.find_points_along_path(kpath.get_cart_coords())
        assert len(r.ikfound) == len(kpath)
        self.assert_equal(
            r.ikfound,
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0])

        #kpath = IrredZone.from_kppa(structure, kppa=1000, shiftk=[0.5, 0.5, 0.5], kptopt=1, verbose=1)
        #assert not kpath.is_ibz and kpath.is_path
        #assert len(kpath) == 60
        #self.assert_equal(kpath.ksampling.mpdivs, [8, 8, 8])

        segments = build_segments(
            k0_list=(0, 0, 0),
            npts=1,
            step=0.01,
            red_dirs=(1, 0, 0),
            reciprocal_lattice=structure.reciprocal_lattice)
        assert len(segments) == 1
        assert np.all(segments[0] == (0, 0, 0))

        step, npts = 0.1, 5
        red_dir = np.array((1, 1, 0))
        segments = build_segments(
            k0_list=(0, 0, 0, 0.5, 0, 0),
            npts=npts,
            step=step,
            red_dirs=red_dir,
            reciprocal_lattice=structure.reciprocal_lattice)

        #print("segments:\n", segments)
        # (nk0_list, len(red_dirs) * npts, 3)
        assert segments.shape == (2, npts, 3)
        self.assert_almost_equal(segments[0, 2], (0, 0, 0))
        self.assert_almost_equal(segments[1, 2], (0.5, 0.0, 0))

        def r2c(vec):
            return structure.reciprocal_lattice.get_cartesian_coords(vec)

        cart_vers = r2c(red_dir)
        cart_vers /= np.linalg.norm(cart_vers)
        self.assert_almost_equal(r2c(segments[1, 1] - segments[1, 0]),
                                 step * cart_vers)
        self.assert_almost_equal(r2c(segments[1, 3] - segments[1, 2]),
                                 step * cart_vers)
Exemple #21
0
    def plot(self, qpoint=None, spin=None, kpoints=None, color_map=None, **kwargs):
        """
        Plot the dipole matrix elements.

        Args:
            qpoint:
                The qpoint for the optical limit.
                if qpoint is None, we plot  |<k|r|k>| else |<k|q.r|k>|
            spin:
                spin index. None if all spins are wanted
            kpoints:
                List of Kpoint objects, None if all k-points are wanted.

        ==============  ==============================================================
        kwargs          Meaning
        ==============  ==============================================================
        title           Title of the plot (Default: None).
        show            True to show the figure (Default).
        savefig:        'abc.png' or 'abc.eps'* to save the figure to a file.
        colormap        matplotlib colormap, see link below.
        ==============  ==============================================================

        Returns:
            matplotlib figure.

        .. see: 
            http://matplotlib.sourceforge.net/examples/pylab_examples/show_colormaps.html
        """
        title = kwargs.pop("title", None)
        show = kwargs.pop("show", True)
        savefig = kwargs.pop("savefig", None)
        color_map = kwargs.pop("color_map", None)

        if qpoint is not None:
            # Will compute scalar product with q
            qpoint = Kpoint.askpoint(qpoint, self.structure.reciprocal_lattice).versor()
        else:
            # Will plot |<psi|r|psi>|.
            qpoint = Kpoint((1, 1, 1), self.structure.reciprocal_lattice)

        if spin in None:
            spins = range(self.nsppol)
        else:
            spins = [spin]

        if kpoints is None:
            kpoints = self.ibz

        # Extract the matrix elements for the plot.
        from abipy.tools.plotting_utils import ArrayPlotter
        plotter = ArrayPlotter()
        for spin in spins:
            for kpoint in kpoints:
                ik = self.kpoint_index(kpoint)
                rme = self.dipme_scvk[spin, ik, :, :, :]

                #qrme = qpoint * rme
                label = "qpoint %s, spin %s, kpoint = %s" % (qpoint, spin, kpoint)
                plotter.add_array(label, rme)

        # Plot matrix elements and return matplotlib figure.
        return plotter.plot(title=title, color_map=color_map, show=show, savefig=savefig, **kwargs)
Exemple #22
0
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