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())
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)
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.")
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)
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
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
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
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)
from pymatgen.io.vasp.outputs import Xdatcar xdat = Xdatcar('XDATCAR') for j, i in enumerate(xdat.structures): i.to('POSCAR', f'POSCAR{j:02d}')
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')
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
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()