Ejemplo n.º 1
0
    def test_init(self):
        filepath = os.path.join(test_dir, 'XDATCAR_4')
        x = Xdatcar(filepath)
        structures = x.structures
        self.assertEqual(len(structures), 4)
        for s in structures:
            self.assertEqual(s.formula, "Li2 O1")

        filepath = os.path.join(test_dir, 'XDATCAR_5')
        x = Xdatcar(filepath)
        structures = x.structures
        self.assertEqual(len(structures), 4)
        for s in structures:
            self.assertEqual(s.formula, "Li2 O1")

        x.concatenate(os.path.join(test_dir, 'XDATCAR_4'))
        self.assertEqual(len(x.structures), 8)
        self.assertIsNotNone(x.get_string())
Ejemplo n.º 2
0
    def from_file(cls, filename, constant_lattice=True, **kwargs):
        """
        Convenience constructor to obtain trajectory from XDATCAR or vasprun.xml file
        Args:
            filename (str): The filename to read from.
            constant_lattice (bool): Whether the lattice changes during the simulation, such as in an NPT MD
                simulation. True results in
        Returns:
            (Trajectory)
        """
        # TODO: Support other filetypes

        fname = os.path.basename(filename)
        if fnmatch(fname, "*XDATCAR*"):
            structures = Xdatcar(filename).structures
        elif fnmatch(fname, "vasprun*.xml*"):
            structures = Vasprun(filename).structures
        else:
            raise ValueError("Unsupported file")

        return cls.from_structures(structures,
                                   constant_lattice=constant_lattice,
                                   **kwargs)
Ejemplo n.º 3
0
 def test_average_coordination_number(self):
     xdatcar = Xdatcar(os.path.join(test_dir, 'XDATCAR.MD'))
     coordination_numbers = average_coordination_number(xdatcar.structures,
                                                        freq=1)
     self.assertAlmostEqual(coordination_numbers['Fe'], 4.771903318390836, 5,
                            "Coordination number not calculated properly.")
Ejemplo n.º 4
0
 def setUp(self):
     self.ss = Xdatcar(os.path.join(test_dir, 'XDATCAR.MD')).structures
     self.s = self.ss[1]
     self.va = VoronoiAnalyzer(cutoff=4.0)
Ejemplo n.º 5
0
 def setUp(self):
     xdatcar = Xdatcar(os.path.join(test_dir, "Traj_XDATCAR"))
     self.traj = Trajectory.from_file(os.path.join(test_dir,
                                                   "Traj_XDATCAR"))
     self.structures = xdatcar.structures
Ejemplo n.º 6
0
 def setUp(self):
     xdatcar = Xdatcar(os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_XDATCAR"))
     self.traj = Trajectory.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "Traj_XDATCAR"))
     self.structures = xdatcar.structures
Ejemplo n.º 7
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
Ejemplo n.º 8
0
 def setUp(self):
     self.ss = Xdatcar(
         os.path.join(PymatgenTest.TEST_FILES_DIR, "XDATCAR.MD")).structures
     self.s = self.ss[1]
     self.va = VoronoiAnalyzer(cutoff=4.0)
Ejemplo n.º 9
0
from pymatgen.io.vasp.outputs import Xdatcar

xdat = Xdatcar('XDATCAR')
for j, i in enumerate(xdat.structures):
    i.to('POSCAR', f'POSCAR{j:02d}')
Ejemplo n.º 10
0
 def __init__(self):
     self.structures = Xdatcar('XDATCAR').structures
     self.fig, self.ax = plt.subplots()
     self.xdata, self.ydata = [], []
     self.ln, = plt.plot([], [], 'ro', color='black')
Ejemplo n.º 11
0
def main():
    def str_examples():
        return """\
Usage example:
    abistruct.py spglib  filepath             => Read the structure from file and analyze it with spglib.
    abistruct.py convert filepath cif         => Read the structure from file and print CIF file.
    abistruct.py convert filepath abivars     => Print the ABINIT variables defining the structure.
    abistruct.py convert out_HIST abivars     => Read the last structure from the HIST file and
                                                 print the corresponding Abinit variables.
    abistruct.py kpath filepath               => Read structure from filepath and print Abinit variables for k-path.
    abistruct.py bz filepath                  => Read structure from filepath, plot BZ with matplotlib.
    abistruct.py kmesh filepath -m 2 2 2      => Read structure from filepath, call spglib to sample the BZ with a 2,2,2 mesh,
                                                 print points in IBZ with weights.

    abistruct.py abisanitize FILE             => Read structure from FILE, call abisanitize, compare structures and save
                                                 "abisanitized" structure to file.
    abistruct.py conventional FILE            => Read structure from FILE, generate conventional structure
                                                 following doi:10.1016/j.commatsci.2010.05.010
    abistruct.py visualize filepath xcrysden  => Visualize the structure with XcrysDen.
    abistruct.py ipython filepath             => Read structure from filepath and open Ipython terminal.
    abistruct.py notebook filepath            => Read structure from filepath and generate jupyter notebook.
    abistruct.py pmgdata mp-149               => Get structure from pymatgen database and print its JSON representation.
"""

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

    # Parent parser for commands that need to know the filepath
    path_selector = argparse.ArgumentParser(add_help=False)
    path_selector.add_argument(
        'filepath',
        nargs="?",
        help=
        "File with the crystalline structure (netcdf, cif, input files ...)")

    parser = argparse.ArgumentParser(
        epilog=str_examples(),
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('-V',
                        '--version',
                        action='version',
                        version="%(prog)s version " + abilab.__version__)

    spgopt_parser = argparse.ArgumentParser(add_help=False)
    spgopt_parser.add_argument('--symprec',
                               default=1e-3,
                               type=float,
                               help="""\
symprec (float): Tolerance for symmetry finding. Defaults to 1e-3,
    which is fairly strict and works well for properly refined
    structures with atoms in the proper symmetry coordinates. For
    structures with slight deviations from their proper atomic
    positions (e.g., structures relaxed with electronic structure
    codes), a looser tolerance of 0.1 (the value used in Materials
    Project) is often needed.""")
    spgopt_parser.add_argument(
        '--angle-tolerance',
        default=5.0,
        type=float,
        help=
        "angle_tolerance (float): Angle tolerance for symmetry finding. Default: 5.0"
    )

    # Parent parser for common options.
    copts_parser = argparse.ArgumentParser(add_help=False)
    copts_parser.add_argument(
        '-v',
        '--verbose',
        default=0,
        action='count',  # -vv --> verbose=2
        help='verbose, can be supplied multiple times to increase verbosity')
    copts_parser.add_argument(
        '--loglevel',
        default="ERROR",
        type=str,
        help=
        "set the loglevel. Possible values: CRITICAL, ERROR (default), WARNING, INFO, DEBUG"
    )

    # Create the parsers for the sub-commands
    subparsers = parser.add_subparsers(
        dest='command',
        help='sub-command help',
        description="Valid subcommands, use command --help for help")

    p_spglib = subparsers.add_parser(
        'spglib',
        parents=[copts_parser, path_selector, spgopt_parser],
        help="Analyze structure with spglib.")

    # Subparser for convert command.
    p_convert = subparsers.add_parser(
        'convert',
        parents=[copts_parser, path_selector],
        help="Convert structure to the specified format.")
    p_convert.add_argument(
        'format',
        nargs="?",
        default="cif",
        type=str,
        help=
        "Format of the output file (cif, cssr, POSCAR, json, mson, abivars).")

    p_abisanitize = subparsers.add_parser(
        'abisanitize',
        parents=[copts_parser, path_selector, spgopt_parser],
        help=
        "Sanitize structure with abi_sanitize, compare structures and save result to file."
    )
    p_abisanitize.add_argument(
        "--savefile",
        default="",
        type=str,
        help=
        'Save final structure to file. Format is detected from file extensions e.g. Si.cif'
    )

    p_conventional = subparsers.add_parser(
        'conventional',
        parents=[copts_parser, path_selector, spgopt_parser],
        help=
        "Gives a structure with a conventional cell according to certain standards. "
        "The standards are defined in doi:10.1016/j.commatsci.2010.05.010")
    p_conventional.add_argument(
        "--savefile",
        default="",
        type=str,
        help=
        'Save final structure to file. Format is detected from file extensions e.g. Si.cif'
    )

    # Subparser for ipython.
    p_ipython = subparsers.add_parser(
        'ipython',
        parents=[copts_parser, path_selector],
        help="Open IPython shell for advanced operations on structure object.")

    p_notebook = subparsers.add_parser(
        'notebook',
        parents=[copts_parser, path_selector],
        help="Read structure from file and generate jupyter notebook.")
    p_notebook.add_argument('--foreground',
                            action='store_true',
                            default=False,
                            help="Run jupyter notebook in the foreground.")

    # Subparser for kpath.
    p_kpath = subparsers.add_parser(
        'kpath',
        parents=[copts_parser, path_selector],
        help=
        "Read structure from file, generate k-path for band-structure calculations."
    )

    # Subparser for bz.
    p_bz = subparsers.add_parser(
        'bz',
        parents=[copts_parser, path_selector],
        help="Read structure from file, plot Brillouin zone with matplotlib.")

    p_kmesh = subparsers.add_parser(
        'kmesh',
        parents=[copts_parser, path_selector],
        help=("Read structure from filepath, call spglib to sample the BZ,"
              "print k-points in the IBZ with weights."))
    p_kmesh.add_argument("-m",
                         "--mesh",
                         nargs="+",
                         required=True,
                         type=int,
                         help="Mesh divisions e.g. 2 3 4")
    p_kmesh.add_argument(
        "-s",
        "--is_shift",
        nargs="+",
        default=None,
        type=int,
        help=
        ("Three integers (spglib API). The kmesh is shifted along " +
         "the axis in half of adjacent mesh points irrespective of the mesh numbers e.g. 1 1 1 "
         + "Default: Unshited mesh."))
    p_kmesh.add_argument("--no-time-reversal",
                         default=False,
                         action="store_true",
                         help="Don't use time-reversal.")

    # Subparser for visualize command.
    p_visualize = subparsers.add_parser(
        'visualize',
        parents=[copts_parser, path_selector],
        help="Visualize the structure with the specified visualizer")
    p_visualize.add_argument('visualizer',
                             nargs="?",
                             default="vesta",
                             type=str,
                             help=("Visualizer name. "
                                   "List of visualizer supported: %s" %
                                   ", ".join(Visualizer.all_visunames())))

    # Subparser for pmgid command.
    p_pmgdata = subparsers.add_parser(
        'pmgdata',
        parents=[copts_parser],
        help=
        "Get structure from the pymatgen database. Requires internet connection and MAPI_KEY"
    )
    p_pmgdata.add_argument("pmgid",
                           type=str,
                           default=None,
                           help="Pymatgen identifier")
    p_pmgdata.add_argument(
        "--mapi-key",
        default=None,
        help="Pymatgen MAPI_KEY. Use value in .pmgrc.yaml if not specified.")
    p_pmgdata.add_argument("--endpoint",
                           help="Pymatgen database.",
                           default="https://www.materialsproject.org/rest/v2")

    # Subparser for animate command.
    p_animate = subparsers.add_parser(
        'animate',
        parents=[copts_parser, path_selector],
        help=
        "Read structures from HIST or XDATCAR. Print structures in Xrysden AXSF format to stdout"
    )

    # Parse command line.
    try:
        options = parser.parse_args()
    except Exception as exc:
        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.command == "spglib":
        structure = abilab.Structure.from_file(options.filepath)
        print(structure.spglib_summary(verbose=options.verbose))

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

        if options.format == "abivars":
            print(structure.abi_string)
        else:
            s = structure.convert(format=options.format)
            print(s)

    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=True,
            primitive_standard=False)
        index = [options.filepath, "abisanitized"]
        dfs = abilab.frames_from_structures([structure, sanitized],
                                            index=index,
                                            with_spglib=True)

        abilab.print_frame(dfs.lattice, title="Lattice parameters:")
        abilab.print_frame(
            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(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.
        if options.savefile:
            print("Saving abisanitized structure as %s" % options.savefile)
            if os.path.exists(options.savefile):
                raise RuntimeError("%s already exists. Cannot overwrite" %
                                   options.savefile)
            sanitized.to(filename=options.savefile)

    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.frames_from_structures([structure, conv],
                                            index=index,
                                            with_spglib=True)

        abilab.print_frame(dfs.lattice, title="Lattice parameters:")
        #abilab.print_frame(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:")
                print(structure)
                print("\nConventional structure:")
                print(conv)

        # save file.
        if options.savefile:
            print("Saving conventional structure as %s" % options.savefile)
            if os.path.exists(options.savefile):
                raise RuntimeError("%s already exists. Cannot overwrite" %
                                   options.savefile)
            conv.to(filename=options.savefile)

    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.visualizer)
        structure.visualize(options.visualizer)

    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":
        structure = abilab.Structure.from_file(options.filepath)
        structure.show_bz()

    elif options.command == "kmesh":
        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:
            k.print_bz2ibz()

    elif options.command == "pmgdata":
        # Get the Structure corresponding the a material_id.
        structure = abilab.Structure.from_material_id(
            options.pmgid,
            final=True,
            api_key=options.mapi_key,
            endpoint=options.endpoint)
        # Convert to json and print it.
        s = structure.convert(format="json")
        print(s)

    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
Ejemplo n.º 12
0
    def run_task(self, fw_spec):

        get_rdf = self.get('get_rdf') or True
        get_diffusion = self.get('get_diffusion') or True
        get_viscosity = self.get('get_viscosity') or True
        get_vdos = self.get('get_vdos') or True
        get_run_data = self.get('get_run_data') or True
        time_step = self.get('time_step') or 2
        checkpoint_dirs = fw_spec.get('checkpoint_dirs', False)

        calc_dir = get_calc_loc(True, fw_spec["calc_locs"])["path"]
        calc_loc = os.path.join(calc_dir, 'XDATCAR.gz')

        ionic_step_skip = self.get('ionic_step_skip') or 1
        ionic_step_offset = self.get('ionic_step_offset') or 0

        analysis_spec = self.get('analysis_spec') or {}

        if checkpoint_dirs:
            logger.info("LOGGER: Assimilating checkpoint structures")
            ionic_steps = []
            structures = []
            for d in checkpoint_dirs:
                ionic_steps.extend(
                    Vasprun(os.path.join(d, "vasprun.xml.gz")).ionic_steps)

                structures.extend(
                    Vasprun(os.path.join(d, 'vasprun.xml.gz'),
                            ionic_step_skip=ionic_step_skip,
                            ionic_step_offset=ionic_step_offset).structures)

        else:
            structures = Xdatcar(calc_loc).structures

        #write a trajectory file for Dospt
        molecules = []
        for struc in structures:
            molecules.append(
                Molecule(species=struc.species,
                         coords=[s.coords for s in struc.sites]))
        XYZ(mol=molecules).write_file('traj.xyz')

        db_dict = {}
        db_dict.update({'density': float(structures[0].density)})
        db_dict.update(structures[0].composition.to_data_dict)
        db_dict.update({'checkpoint_dirs': checkpoint_dirs})

        if get_rdf:
            logger.info("LOGGER: Calculating radial distribution functions...")
            rdf = RadialDistributionFunction(structures=structures)
            rdf_dat = rdf.get_radial_distribution_functions(nproc=4)
            db_dict.update({'rdf': rdf.get_rdf_db_dict()})
            del rdf
            del rdf_dat

        if get_vdos:
            logger.info("LOGGER: Calculating vibrational density of states...")
            vdos = VDOS(structures)
            vdos_dat = vdos.calc_vdos_spectrum(time_step=time_step *
                                               ionic_step_skip)
            vdos_diff = vdos.calc_diffusion_coefficient(time_step=time_step *
                                                        ionic_step_skip)
            db_dict.update({'vdos': vdos_dat})
            del vdos
            del vdos_dat

        if get_diffusion:
            logger.info("LOGGER: Calculating the diffusion coefficients...")
            diffusion = Diffusion(structures,
                                  t_step=time_step,
                                  l_lim=50,
                                  skip_first=250,
                                  block_l=1000,
                                  ci=0.95)
            D = {'msd': {}, 'vdos': {}}
            for s in structures[0].types_of_specie:
                D['msd'][s.symbol] = diffusion.getD(s.symbol)
            if vdos_diff:
                D['vdos'] = vdos_diff
            db_dict.update({'diffusion': D})
            del D

        if get_viscosity:
            logger.info("LOGGER: Calculating the viscosity...")
            viscosities = []
            if checkpoint_dirs:
                for dir in checkpoint_dirs:
                    visc = Viscosity(dir).calc_viscosity()
                    viscosities.append(visc['viscosity'])
            viscosity_dat = {
                'viscosity': np.mean(viscosities),
                'StdDev': np.std(viscosities)
            }
            db_dict.update({'viscosity': viscosity_dat})
            del viscosity_dat

        if get_run_data:
            if checkpoint_dirs:
                logger.info("LOGGER: Assimilating run stats...")
                data = MD_Data()
                for directory in checkpoint_dirs:
                    data.parse_md_data(directory)
                md_stats = data.get_md_stats()
            else:
                logger.info("LOGGER: Getting run stats...")
                data = MD_Data()
                data.parse_md_data(calc_dir)
                md_stats = data.get_md_stats()
            db_dict.update({'md_data': md_stats})

        if analysis_spec:
            logger.info("LOGGER: Adding user-specified data...")
            db_dict.update(analysis_spec)

        logger.info("LOGGER: Pushing data to database collection...")
        db_file = env_chk(">>db_file<<", fw_spec)
        db = VaspCalcDb.from_db_file(db_file, admin=True)
        db.collection = db.db["md_data"]
        db.collection.insert_one(db_dict)

        return FWAction()