def test_visualizers(self): print("Available visualizers:") for vclass in Visualizer.get_available(): print(vclass) assert Xcrysden.support_ext("xsf") and Xcrysden.support_ext(".xsf") assert Vesta is Visualizer.from_name("vesta") assert Vesta.support_ext( "xsf") and "xsf" in Vesta.supported_extensions() #assert Vesta.from_file("foo.xsf") with self.assertRaises(Visualizer.Error): Visualizer.from_name("foobar") assert len(Visualizer.all_visunames()) assert V_Sim.support_ext("xsf") for cls in [Xcrysden, V_Sim, Vesta, Ovito, Avogadro]: visu = cls("foo.xsf") assert callable(visu) repr(visu) str(visu) # cmdarg is a string? assert visu.cmdarg + " " assert visu.is_available in (True, False)
def test_visualizers(self): print("Available visualizers:") for vclass in Visualizer.get_available(): print(vclass) assert Xcrysden.support_ext("xsf") and Xcrysden.support_ext(".xsf") assert Vesta is Visualizer.from_name("vesta") assert Vesta.support_ext( "xsf") and "xsf" in Vesta.supported_extensions() #assert Vesta.from_file("foo.xsf") assert V_Sim.support_ext("xsf")
def CreateStructureMenu(self): """Creates the structure menu.""" # Structure Menu ID's self.ID_STRUCT_CONVERT = wx.NewId() self.ID_STRUCT_VISUALIZE = wx.NewId() self.ID_STRUCT_SHOWBZ = wx.NewId() menu = wx.Menu() menu.Append(self.ID_STRUCT_CONVERT, "Convert", "Convert structure data to cif, POSCAR ...") self.Bind(wx.EVT_MENU, self.OnStructureConvert, id=self.ID_STRUCT_CONVERT) menu.Append(self.ID_STRUCT_SHOWBZ, "Show BZ", "Visualize the first Brillouin zone with matplotlib.") self.Bind(wx.EVT_MENU, self.OnStructureShowBz, id=self.ID_STRUCT_SHOWBZ) # Make sub-menu with the list of supported visualizers. visu_menu = wx.Menu() self._id2visuname = {} available_visus = [visu.name for visu in Visualizer.get_available()] for visu_name in available_visus: _id = wx.NewId() visu_menu.Append(_id, visu_name) self._id2visuname[_id] = visu_name self.Bind(wx.EVT_MENU, self.OnStructureVisualize, id=_id) menu.AppendMenu(-1, 'Visualize', visu_menu) return menu
def makeToolBar(self): """Creates the toolbar.""" self.toolbar = toolbar = self.CreateToolBar() toolbar.SetToolBitmapSize(wx.Size(48, 48)) def bitmap(path): return wx.Bitmap(awx.path_img(path)) artBmp = wx.ArtProvider.GetBitmap toolbar.AddSimpleTool(wx.ID_OPEN, artBmp(wx.ART_FILE_OPEN, wx.ART_TOOLBAR), "Open") toolbar.AddSeparator() # Combo box with the list of visualizers avail_visunames = [visu.name for visu in Visualizer.get_available()] value = avail_visunames[0] if avail_visunames else "None" self.visualizer_cbox = wx.ComboBox(toolbar, id=-1, name='visualizer', choices=avail_visunames, value=value, style=wx.CB_READONLY) toolbar.AddControl(control=self.visualizer_cbox) toolbar.Realize()
def CreateStructureMenu(self): """Creates the structure menu.""" # Structure Menu ID's self.ID_STRUCT_CONVERT = wx.NewId() self.ID_STRUCT_VISUALIZE = wx.NewId() self.ID_STRUCT_SHOWBZ = wx.NewId() menu = wx.Menu() menu.Append(self.ID_STRUCT_CONVERT, "Convert", "Convert structure data to cif, POSCAR ...") self.Bind(wx.EVT_MENU, self.OnStructureConvert, id=self.ID_STRUCT_CONVERT) menu.Append(self.ID_STRUCT_SHOWBZ, "Show BZ", "Visualize the first Brillouin zone with matplotlib.") self.Bind(wx.EVT_MENU, self.OnStructureShowBz, id=self.ID_STRUCT_SHOWBZ) # Make sub-menu with the list of supported visualizers. visu_menu = wx.Menu() self._id2visuname = {} available_visus = [visu.name for visu in Visualizer.get_available()] for appname in available_visus: _id = wx.NewId() visu_menu.Append(_id, appname) self._id2visuname[_id] = appname self.Bind(wx.EVT_MENU, self.OnStructureVisualize, id=_id) menu.AppendMenu(-1, 'Visualize', visu_menu) return menu
def showStructure(parent, filepath): ncfile = abiopen(filepath) visu_classes = Visualizer.get_available(ext="xsf") if not visu_classes: print("Not visualizer found for extension xsf") return vname = visu_classes[0].name visu = ncfile.structure.visualize(vname) thread = awx.WorkerThread(parent, target=visu) thread.start()
def visualize_structure_with(self, visu_name): """ Visualize the crystalline structure with the specified visualizer. See :class:`Visualizer` for the list of applications and formats supported. """ visu = Visualizer.from_name(visu_name) for ext in visu.supported_extensions(): ext = "." + ext try: return self.export_structure(ext) except visu.Error: pass else: raise visu.Error("Don't know how to export data for visu_name %s" % visu_name)
def visualize_structure_with(self, appname): """ Visualize the crystalline structure with the specified visualizer. See |Visualizer| for the list of applications and formats supported. """ from abipy.iotools.visualizer import Visualizer visu = Visualizer.from_name(appname) for ext in visu.supported_extensions(): ext = "." + ext try: return self.export_structure(ext) except visu.Error: pass else: raise visu.Error("Don't know how to export data for appname %s" % appname)
def visualize_structure_with(self, visualizer): """ Visualize the crystalline structure with visualizer. See :class:`Visualizer` for the list of applications and formats supported. """ extensions = Visualizer.exts_from_appname(visualizer) for ext in extensions: ext = "." + ext try: return self.export_structure(ext) except Visualizer.Error: pass else: raise Visualizer.Error( "Don't know how to export data for visualizer %s" % visualizer)
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. abistrcut.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 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 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.") # Subparser for bz. p_bz = subparsers.add_parser( 'bz', parents=[copts_parser, path_selector], help="Read structure from file, plot Brillouin zone with matplotlib.") # Subparser for bz. 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 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 env variable if not specified.") p_pmgdata.add_argument("--endpoint", default="www.materialsproject.org", help="Pymatgen database.") # 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 == "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 == "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": from abipy.iotools import xsf_write_structure 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: from pymatgen.io.vaspio import Xdatcar 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 main(): def str_examples(): examples = """\ Usage example:\n 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. abistrctu.py convert out_HIST abivars => Read the last structure from the HIST file and print the corresponding Abinit variables. abistruct.py visualize filepath xcrysden => Visualize the structure with XcrysDen. abistruct.py pmgdata mp-149 => Get structure from pymatgen database and print its JSON representation. """ return examples 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") parser = argparse.ArgumentParser(epilog=str_examples(), formatter_class=argparse.RawDescriptionHelpFormatter) # 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") subparsers.add_parser('version', help='Show version number and exit') # Subparser for convert command. p_convert = subparsers.add_parser('convert', parents=[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).") # Subparser for visualize command. p_visualize = subparsers.add_parser('visualize', parents=[path_selector], help="Visualize the structure with the specified visualizer") p_visualize.add_argument('visualizer', nargs="?", default="xcrysden", type=str, help=("Visualizer name. " "List of visualizer supported: %s" % ", ".join(Visualizer.all_visunames()))) # Subparser for pmgid command. p_pmgdata = subparsers.add_parser('pmgdata', 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 env variable if not specified.") p_pmgdata.add_argument("--host", default="www.materialsproject.org", help="Pymatgen database.") # Subparser for animate command. p_animate = subparsers.add_parser('animate', parents=[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: show_examples_and_exit(error_code=1) if options.command == "version": from abipy.core.release import version print(version) return 0 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 == "visualize": structure = abilab.Structure.from_file(options.filepath) structure.visualize(options.visualizer) 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, host=options.host) # Convert to json and print it. s = structure.convert(format="json") #s = structure.convert(format="mson") print(s) elif options.command == "animate": from abipy.iotools import xsf_write_structure 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: from pymatgen.io.vaspio import Xdatcar structures = Xdatcar(filepath).structures if not structures: raise RuntimError("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 main(): def str_examples(): return """\ Usage example: 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 visualize filepath xcrysden => Visualize the structure with XcrysDen. abistruct.py ipython filepath => Read structure from filepath and open Ipython terminal. abistruct.py bz filepath => Read structure from filepath, plot BZ with matplotlib. 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") parser = argparse.ArgumentParser(epilog=str_examples(), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version="%(prog)s version " + abilab.__version__) # 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") # 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).") # Subparser for ipython. p_ipython = subparsers.add_parser('ipython', parents=[copts_parser, path_selector], help="Open IPython shell for advanced operations on structure object.") # Subparser for bz. p_bz = subparsers.add_parser('bz', parents=[copts_parser, path_selector], help="Read structure from file, plot Brillouin zone with matplotlib.") # 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="xcrysden", 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 env variable if not specified.") p_pmgdata.add_argument("--endpoint", default="www.materialsproject.org", help="Pymatgen database.") # 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 == "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 == "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 == "visualize": structure = abilab.Structure.from_file(options.filepath) structure.visualize(options.visualizer) elif options.command == "bz": structure = abilab.Structure.from_file(options.filepath) structure.show_bz() 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") #s = structure.convert(format="mson") print(s) elif options.command == "animate": from abipy.iotools import xsf_write_structure 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: from pymatgen.io.vaspio import Xdatcar 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 get_parser(with_epilog=False): # Parent parser for common options. copts_parser = argparse.ArgumentParser(add_help=False) copts_parser.add_argument('filepath', type=str, help="File to visualize.") copts_parser.add_argument( '--loglevel', default="ERROR", type=str, help= "Set the loglevel. Possible values: CRITICAL, ERROR (default), WARNING, INFO, DEBUG" ) 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( '-sns', "--seaborn", const="paper", default=None, action='store', nargs='?', type=str, help= 'Use seaborn settings. Accept value defining context in ("paper", "notebook", "talk", "poster"). Default: paper' ) copts_parser.add_argument( '-mpl', "--mpl-backend", default=None, help= ("Set matplotlib interactive backend. " "Possible values: GTKAgg, GTK3Agg, GTK, GTKCairo, GTK3Cairo, WXAgg, WX, TkAgg, Qt4Agg, Qt5Agg, macosx." "See also: https://matplotlib.org/faq/usage_faq.html#what-is-a-backend." )) # Parent parser for commands supporting MplExpose. slide_parser = argparse.ArgumentParser(add_help=False) slide_parser.add_argument( "-s", "--slide-mode", default=False, action="store_true", help= "Iterate over figures. Expose all figures at once if not given on the CLI." ) slide_parser.add_argument( "-t", "--slide-timeout", type=int, default=None, help= "Close figure after slide-timeout seconds (only if slide-mode). Block if not specified." ) # Parent parser for commands supporting ipython ipy_parser = argparse.ArgumentParser(add_help=False) ipy_parser.add_argument('-ipy', '--ipython', default=False, action="store_true", help='Invoke ipython terminal.') # Parent parser for commands supporting (jupyter notebooks) nb_parser = argparse.ArgumentParser(add_help=False) nb_parser.add_argument('-nb', '--notebook', default=False, action="store_true", help='Generate jupyter notebook.') nb_parser.add_argument('--foreground', action='store_true', default=False, help="Run jupyter notebook in the foreground.") # Parent parser for commands supporting expose. #expose_parser = argparse.ArgumentParser(add_help=False) #expose_parser.add_argument("-e", '--expose', default=False, action="store_true", # help='Execute robot.expose to produce a pre-defined list of matplotlib figures.') #expose_parser.add_argument("-s", "--slide-mode", default=False, action="store_true", # help="Used if --expose to iterate over figures. Expose all figures at once if not given on the CLI.") #expose_parser.add_argument("-t", "--slide-timeout", type=int, default=None, # help="Close figure after slide-timeout seconds (only if slide-mode). Block if not specified.") # Build the main parser. parser = argparse.ArgumentParser( epilog=get_epilog() if with_epilog else "", formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version=abilab.__version__) # Create the parsers for the sub-command subparsers = parser.add_subparsers(dest='command', help='sub-command help', description="Valid subcommands") def add_args(p, *args): """Add arguments to subparser `p`.""" for arg in args: if arg == "xmgrace": p.add_argument( '--xmgrace', default=False, action="store_true", help="Print bands in xmgrace format to stdout and exit.") elif arg == "bxsf": p.add_argument( '--bxsf', default=False, action="store_true", help= ("Generate BXSF file suitable for the visualization of isosurfaces with Xcrysden" "(xcrysden --bxsf FILE).\n Requires k-points in IBZ. Print to stdout and exit." )) elif arg == "phononweb": p.add_argument( "-web", "--phononwebsite", default=False, action="store_true", help=( "Visualize phonon band structure on the phononwebsite. " "http://henriquemiranda.github.io/phononwebsite/")) elif arg == "browser": p.add_argument( "-b", "--browser", default=None, help="Define browser used by python webbrowser. " "See https://docs.python.org/2/library/webbrowser.html#webbrowser.register" ) elif arg == "force": p.add_argument( "-f", '--force', default=False, action="store_true", help= "Overwrite pre-existent files without prompting for confirmation." ) else: raise ValueError("Invalid arg: %s" % arg) # Subparser for structure command. p_structure = subparsers.add_parser('structure', parents=[copts_parser], help=abiview_structure.__doc__) p_structure.add_argument("-a", "--appname", nargs="?", type=str, default="vesta", help=("Application name. Default: vesta. " "Possible options: %s, mayavi, vtk" % ", ".join(Visualizer.all_visunames()))) # Subparser for hist command. p_hist = subparsers.add_parser('hist', parents=[copts_parser], help=abiview_hist.__doc__) p_hist.add_argument( "-a", "--appname", nargs="?", default=None, const="ovito", help=("Application name. Default: ovito. " "Possible options: `%s`, `mpl` (matplotlib) `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) p_hist.add_argument("--xdatcar", default=False, action="store_true", help="Convert HIST file into XDATCAR format.") p_hist.add_argument("--to-unit-cell", default=False, action="store_true", help="Whether to translate sites into the unit cell.") add_args(p_hist, "force") # Subparser for data command. p_data = subparsers.add_parser('data', parents=[copts_parser], help=abiview_data.__doc__) p_data.add_argument( "-i", "--use-index", default=False, action="store_true", help= "Use the row index as x-value in the plot. By default the plotter uses the first column as x-values" ) # Subparser for abo command. #p_abo = subparsers.add_parser('abo', parents=[copts_parser], help=abiview_abo.__doc__) # Subparser for log command. p_dirviz = subparsers.add_parser('dirviz', parents=[copts_parser], help=abiview_dirviz.__doc__) p_dirviz.add_argument( "-e", "--engine", type=str, default="fdp", help= ("graphviz engine: ['dot', 'neato', 'twopi', 'circo', 'fdp', 'sfdp', 'patchwork', 'osage']. " "See http://www.graphviz.org/pdf/dot.1.pdf " "Use `conda install python-graphviz` or `pip install graphviz` to install the python package" )) # Subparser for ebands command. p_ebands = subparsers.add_parser('ebands', parents=[copts_parser, slide_parser], help=abiview_ebands.__doc__) add_args(p_ebands, "xmgrace", "bxsf", "force") # Subparser for ebands command. p_skw = subparsers.add_parser('skw', parents=[copts_parser], help=abiview_skw.__doc__) p_skw.add_argument( "-lp", "--lpratio", type=int, default=5, help= ("Ratio between the number of star functions and the number of ab-initio k-points. " "The default should be OK in many systems, larger values may be required for accurate derivatives." )) p_skw.add_argument( "-ld", "--line-density", type=int, default=20, help="Number of points in the smallest segment of the k-path.") # Subparser for fs command. p_fs = subparsers.add_parser('fs', parents=[copts_parser], help=abiview_fs.__doc__) p_fs.add_argument( "-a", "--appname", type=str, default="mpl", help= "Application name. Possible options: mpl (matplotlib, default), xsf (xcrysden), mayavi." ) # Subparser for ddb command. p_ddb = subparsers.add_parser('ddb', parents=[copts_parser, slide_parser], help=abiview_ddb.__doc__) add_args(p_ddb, "xmgrace", "phononweb", "browser", "force") # Subparser for phbands command. p_phbands = subparsers.add_parser('phbands', parents=[copts_parser, slide_parser], help=abiview_phbands.__doc__) add_args(p_phbands, "xmgrace", "phononweb", "browser", "force") # Subparser for lobster command. p_lobster = subparsers.add_parser( 'lobster', parents=[copts_parser, ipy_parser, nb_parser], help=abiview_lobster.__doc__) p_lobster.add_argument("--prefix", type=str, default="", help="Prefix for lobster output files. Default: ''") # Subparser for denpot command. #p_denpot = subparsers.add_parser('denpot', parents=[copts_parser], help=abiview_denpot.__doc__) #p_denpot.add_argument("-a", "--appname", nargs="?", default=None, const="vesta", # help=("Application name. Default: vesta. " # "Possible options: `%s`, `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) #p_denpot.add_argument("--chgcar", default=False, action="store_true", "Convert Density to CHGCAR format.") #p_denpot.add_argument("--cube", default=False, action="store_true", "Convert Density/Potential to CUBE format.") return parser
def get_parser(with_epilog=False): # 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 (Abinit Netcdf files, CIF, Abinit input/output files, POSCAR ...)") # Parent parser for commands supporting (jupyter notebooks) nb_parser = argparse.ArgumentParser(add_help=False) nb_parser.add_argument('-nb', '--notebook', default=False, action="store_true", help='Generate jupyter notebook.') nb_parser.add_argument('--foreground', action='store_true', default=False, help="Run jupyter notebook in the foreground.") parser = argparse.ArgumentParser(epilog=get_epilog() if with_epilog else "", formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version=abilab.__version__) # Parser for commands that need to call spglib. 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") spgopt_parser.add_argument("--no-time-reversal", default=False, action="store_true", help="Don't use time-reversal.") # 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") # Parent parser for commands that need to save structure to file. savefile_parser = argparse.ArgumentParser(add_help=False) savefile_parser.add_argument("-s", "--savefile", default="", type=str, help="Save final structure to file. Format is detected from file extensions " "e.g. out.abi for Abinit input, out.cif for CIF format.") # Helper functions to construct sub-parsers. def add_primitive_options(parser): """Add --no-primitive and --primitive-standard options to a parser.""" group = parser.add_mutually_exclusive_group() group.add_argument('--no-primitive', default=False, action='store_true', help="Do not enforce primitive cell.") group.add_argument('--primitive-standard', default=False, action='store_true', help="Enforce primitive standard cell.") supported_formats = "(abivars, cif, xsf, poscar, qe, siesta, wannier90, cssr, json, None)" def add_format_arg(parser, default, option=True, formats=None): """Add --format option to a parser with default value `default`.""" formats = supported_formats if formats is None else formats if option: parser.add_argument("-f", "--format", default=default, type=str, help="Output format. Default: %s. Accept: %s" % (default, formats)) else: parser.add_argument('format', nargs="?", default=default, type=str, help="Output format. Default: %s. Accept: %s" % (default, formats)) # 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") # Subparser for spglib command. p_spglib = subparsers.add_parser('spglib', parents=[copts_parser, path_selector, spgopt_parser], help="Analyze structure with spglib.") # Subparser for abispg command. p_abispg = subparsers.add_parser('abispg', parents=[copts_parser, path_selector, savefile_parser], help="Extract/Compute Abinit space group from file with structure.") p_abispg.add_argument("-t", "--tolsym", type=float, default=None, help="""\ Gives the tolerance on the atomic positions (reduced coordinates), primitive vectors, or magnetization, to be considered equivalent, thanks to symmetry operations. This is used in the recognition of the set of symmetries of the system, or the application of the symmetry operations to generate from a reduced set of atoms, the full set of atoms. Note that a value larger than 0.01 is considered to be unacceptable.""") p_abispg.add_argument("-d", "--diff-mode", type=str, default="table", choices=["table", "diff"], help="Select diff output format.") # Subparser for convert command. p_convert = subparsers.add_parser('convert', parents=[copts_parser, path_selector], help="Convert structure to the specified format.") add_format_arg(p_convert, default="cif") # Subparser for supercell command. p_supercell = subparsers.add_parser('supercell', parents=[copts_parser, path_selector], help="Generate supercell.") p_supercell.add_argument("-s", "--scaling_matrix", nargs="+", required=True, type=int, help="""\ scaling_matrix: A scaling matrix for transforming the lattice vectors. Has to be all integers. Several options are possible: a. A full 3x3 scaling matrix defining the linear combination the old lattice vectors. E.g., -s 2,1,0 0,3,0, 0,0,1 generates a new structure with lattice vectors a' = 2a + b, b' = 3b, c' = c where a, b, and c are the lattice vectors of the original structure. b. An sequence of three scaling factors. E.g., -s 2, 1, 1 specifies that the supercell should have dimensions 2a x b x c. c. A number, which simply scales all lattice vectors by the same factor. """) add_format_arg(p_supercell, default="abivars") # Subparser for abisanitize p_abisanitize = subparsers.add_parser('abisanitize', parents=[copts_parser, path_selector, spgopt_parser, savefile_parser], help="Sanitize structure with abi_sanitize, compare structures and save result to file.") add_primitive_options(p_abisanitize) # Subparser for irefine p_irefine = subparsers.add_parser('irefine', parents=[copts_parser, path_selector, spgopt_parser], help="Refine structure with abi_sanitize iteratively, stop if target space group is obtained.") p_irefine.add_argument("--target-spgnum", required=True, type=int, help="Target space group number.") p_irefine.add_argument("--symprec-step", default=0.05, type=float, help='Increment for symprec.') p_irefine.add_argument("--angle-tolerance-step", default=0.0, type=float, help='Increment for angle_tolerance.') p_irefine.add_argument("--ntrial", default=50, type=int, help='Number of trials. Default 50.') add_primitive_options(p_irefine) # Subparser for conventional. p_conventional = subparsers.add_parser('conventional', parents=[copts_parser, path_selector, spgopt_parser, savefile_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") # Subparser for neighbors. p_neighbors = subparsers.add_parser('neighbors', parents=[copts_parser, path_selector], help="Get neighbors for each atom in the unit cell, out to a distance radius.") p_neighbors.add_argument("-r", "--radius", default=2, type=float, help="Radius of the sphere in Angstrom.") # Subparser for interpolate. p_interpolate = subparsers.add_parser('interpolate', parents=[copts_parser], help=("Interpolate between two structures. Useful for the construction of NEB inputs.")) p_interpolate.add_argument("filepaths", nargs=2, help="Files with initial and final structures.") p_interpolate.add_argument("-n", "--nimages", default=10, type=int, help="No. of interpolation images. Defaults to 10.") p_interpolate.add_argument("--autosort_tol", default=0.5, type=float, help="""\ A distance tolerance in Angstrom in which to automatically sort end_structure to match to the closest points in this particular structure. This is usually what you want in a NEB calculation. 0 implies no sorting. Otherwise, a 0.5 value (default) usually works pretty well.""") add_format_arg(p_interpolate, default="abivars") # Subparser for xrd. p_xrd = subparsers.add_parser('xrd', parents=[copts_parser, path_selector], help="X-ray diffraction plot.") p_xrd.add_argument("-w", "--wavelength", default="CuKa", type=str, help=( "The wavelength can be specified as a string. It must be one of the " "supported definitions in the WAVELENGTHS dict declared in pymatgen/analysis/diffraction/xrd.py." "Defaults to 'CuKa', i.e, Cu K_alpha radiation.")) p_xrd.add_argument("-s", "--symprec", default=0, type=float, help=( "Symmetry precision for structure refinement. " "If set to 0, no refinement is done. Otherwise, refinement is performed using spglib with provided precision.")) p_xrd.add_argument("-t", "--two-theta-range", default=(0, 90), nargs=2, help=( "Tuple for range of two_thetas to calculate in degrees. Defaults to (0, 90).")) p_xrd.add_argument("-nap", "--no-annotate-peaks", default=False, action="store_true", help="Whether to annotate the peaks with plane information.") # Subparser for oxistate. p_oxistate = subparsers.add_parser('oxistate', parents=[copts_parser, path_selector], help="Estimate oxidation states with pymatgen bond valence analysis.") # Subparser for ipython. p_ipython = subparsers.add_parser('ipython', parents=[copts_parser, path_selector], help="Open IPython shell for advanced operations on structure object.") # Subparser for notebook. 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.") add_format_arg(p_kpath, default="abinit", formats=["abinit", "wannier90", "siesta"]) # Subparser for bz. p_bz = subparsers.add_parser('bz', parents=[copts_parser, path_selector], help="Read structure from file, plot Brillouin zone with matplotlib.") # Subparser for ngkpt. p_ngkpt = subparsers.add_parser('ngkpt', parents=[copts_parser, path_selector], help="Return the Abinit k-point sampling variables " "from the number of divisions used to sample the smallest " "lattice vector of the reciprocal lattice.") p_ngkpt.add_argument("-n", "--nksmall", required=True, type=int, help="Number of divisions used to sample the smallest reciprocal lattice vector.") # Subparser for ktables. p_ktables = subparsers.add_parser('ktables', 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_ktables.add_argument("-m", "--mesh", nargs=3, required=True, type=int, help="Mesh divisions e.g. 2 3 4") p_ktables.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: Unshifted mesh.")) p_ktables.add_argument("--no-time-reversal", default=False, action="store_true", help="Don't use time-reversal.") # Subparser for abikmesh. p_abikmesh = subparsers.add_parser('abikmesh', parents=[copts_parser, path_selector], help=("Read structure from file, call Abinit to sample the BZ with ngkpt, shiftk, and kptopt. " "Print k-points in the IBZ with weights.")) p_abikmesh.add_argument("--kppa", default=None, type=int, help="Number of k-points per reciprocal atom. Mutually exclusive with ngkpt.") p_abikmesh.add_argument("--ngkpt", nargs=3, default=None, type=int, help="Mesh divisions e.g. 2 3 4") p_abikmesh.add_argument("--shiftk", nargs="+", default=(0.5, 0.5, 0.5), type=float, help="Kmesh shifts. Default: 0.5 0.5 0.5") p_abikmesh.add_argument("--kptopt", default=1, type=int, help="Kptopt input variable. Default: 1") # Subparser for kmesh_jhu. #p_kmesh_jhu = subparsers.add_parser('kmesh_jhu', parents=[copts_parser, path_selector], help="Foobar ") # Subparser for lgk. p_lgk = subparsers.add_parser('lgk', parents=[copts_parser, path_selector, spgopt_parser], help="Read structure from file, find little group of k-point, print Bilbao character table.") p_lgk.add_argument("-k", "--kpoint", nargs=3, required=True, type=float, help="K-point in reduced coordinates e.g. 0.25 0 0") # Subparser for kstar. p_kstar = subparsers.add_parser('kstar', parents=[copts_parser, path_selector, spgopt_parser], help="Read structure from file, print star of k-point.") p_kstar.add_argument("-k", "--kpoint", nargs=3, required=True, type=float, help="K-point in reduced coordinates e.g. 0.25 0 0") # Subparser for keq. p_keq = subparsers.add_parser('keq', parents=[copts_parser, path_selector, spgopt_parser], help="Read structure from file, check whether two k-points are equivalent by symmetry.") p_keq.add_argument("-k", "--kpoints", nargs=6, required=True, type=float, help="K-points in reduced coordinates e.g. 0.25 0 0 0 0.25 0") # Subparser for visualize command. p_visualize = subparsers.add_parser('visualize', parents=[copts_parser, path_selector], help=("Visualize the structure with the specified application. " "Requires external app or optional python modules (mayavi, vtk).")) p_visualize.add_argument("-a", "--appname", type=str, default="vesta", help=("Application name. Possible options: %s, mpl (matplotlib), mayavi, vtk" % ", ".join(Visualizer.all_visunames()))) # Options for commands accessing the materials project database. mp_rest_parser = argparse.ArgumentParser(add_help=False) mp_rest_parser.add_argument("--mapi-key", default=None, help="Pymatgen PMG_MAPI_KEY. Use value in .pmgrc.yaml if not specified.") mp_rest_parser.add_argument("--endpoint", help="Pymatgen database.", default="https://www.materialsproject.org/rest/v2") mp_rest_parser.add_argument("-b", "--browser", default=False, action='store_true', help="Open materials-project webpages in browser") # Subparser for mp_id command. p_mpid = subparsers.add_parser('mp_id', parents=[copts_parser, mp_rest_parser], help="Get structure from the pymatgen database. Export to format. Requires internet connection and PMG_MAPI_KEY.") p_mpid.add_argument("mpid", type=str, default=None, help="Pymatgen identifier.") add_format_arg(p_mpid, default="cif") # Subparser for mp_match command. p_mpmatch = subparsers.add_parser('mp_match', parents=[path_selector, mp_rest_parser, copts_parser, nb_parser], help="Get structure from the pymatgen database. Requires internet connection and PMG_MAPI_KEY.") add_format_arg(p_mpmatch, default="abivars") # Subparser for mp_search command. p_mpsearch = subparsers.add_parser('mp_search', parents=[mp_rest_parser, copts_parser, nb_parser], help="Get structure from the pymatgen database. Requires internet connection and PMG_MAPI_KEY") p_mpsearch.add_argument("chemsys_formula_id", type=str, default=None, help="A chemical system (e.g., Li-Fe-O), or formula (e.g., Fe2O3) or materials_id (e.g., mp-1234).") p_mpsearch.add_argument("-s", "--select-spgnum", type=int, default=None, help="Select structures with this space group number.") add_format_arg(p_mpsearch, default="abivars") # Subparser for mp_pd command. p_mp_pda = subparsers.add_parser('mp_pd', parents=[mp_rest_parser, copts_parser], help=("Generate phase diagram with entries from the Materials Project. " "Requires internet connection and PMG_MAPI_KEY")) p_mp_pda.add_argument("file_or_elements", type=str, default=None, help="FILE with structure or elements e.g., Li-Fe-O).") p_mp_pda.add_argument("-u", "--show-unstable", type=int, default=0, help="""Whether unstable phases will be plotted as well as red crosses. If a number > 0 is entered, all phases with ehull < show_unstable will be shown.""") # Subparser for cod_search command. p_codsearch = subparsers.add_parser('cod_search', parents=[copts_parser, nb_parser], help="Get structure from COD database. Requires internet connection and mysql") p_codsearch.add_argument("formula", type=str, default=None, help="formula (e.g., Fe2O3).") p_codsearch.add_argument("-s", "--select-spgnum", type=int, default=None, help="Select structures with this space group number.") p_codsearch.add_argument('--primitive', default=False, action='store_true', help="Convert COD cells into primitive cells.") add_format_arg(p_codsearch, default="abivars") # Subparser for cod_id command. p_codid = subparsers.add_parser('cod_id', parents=[copts_parser], help="Get structure from COD database. Requires internet connection and mysql") p_codid.add_argument("cod_identifier", type=int, default=None, help="COD identifier.") p_codid.add_argument('--primitive', default=False, action='store_true', help="Convert COD cell into primitive cell.") add_format_arg(p_codid, default="abivars") # Subparser for animate command. p_animate = subparsers.add_parser('animate', parents=[copts_parser, path_selector], help="Read structures from HIST.nc or XDATCAR. Print structures in Xcrysden AXSF format to stdout.") return parser
def get_parser(with_epilog=False): # Parent parser for common options. copts_parser = argparse.ArgumentParser(add_help=False) copts_parser.add_argument('filepath', type=str, help="File to visualize.") copts_parser.add_argument('--loglevel', default="ERROR", type=str, help="Set the loglevel. Possible values: CRITICAL, ERROR (default), WARNING, INFO, DEBUG") 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('-sns', "--seaborn", const="paper", default=None, action='store', nargs='?', type=str, help='Use seaborn settings. Accept value defining context in ("paper", "notebook", "talk", "poster"). Default: paper') copts_parser.add_argument('-mpl', "--mpl-backend", default=None, help=("Set matplotlib interactive backend. " "Possible values: GTKAgg, GTK3Agg, GTK, GTKCairo, GTK3Cairo, WXAgg, WX, TkAgg, Qt4Agg, Qt5Agg, macosx." "See also: https://matplotlib.org/faq/usage_faq.html#what-is-a-backend.")) # Parent parser for commands supporting MplExpose. slide_parser = argparse.ArgumentParser(add_help=False) slide_parser.add_argument("-s", "--slide-mode", default=False, action="store_true", help="Iterate over figures. Expose all figures at once if not given on the CLI.") slide_parser.add_argument("-t", "--slide-timeout", type=int, default=None, help="Close figure after slide-timeout seconds (only if slide-mode). Block if not specified.") # Build the main parser. parser = argparse.ArgumentParser(epilog=get_epilog() if with_epilog else "", formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version=abilab.__version__) # Create the parsers for the sub-commands subparsers = parser.add_subparsers(dest='command', help='sub-command help', description="Valid subcommands") def add_args(p, *args): """Add arguments to subparser `p`.""" for arg in args: if arg == "xmgrace": p.add_argument('--xmgrace', default=False, action="store_true", help="Print bands in xmgrace format to stdout and exit.") elif arg == "bxsf": p.add_argument('--bxsf', default=False, action="store_true", help=("Generate BXSF file suitable for the visualization of isosurfaces with Xcrysden" "(xcrysden --bxsf FILE).\n Requires k-points in IBZ. Print to stdout and exit.")) elif arg == "phononweb": p.add_argument("-web", "--phononwebsite", default=False, action="store_true", help=("Visualize phonon band structure on the phononwebsite. " "http://henriquemiranda.github.io/phononwebsite/")) elif arg == "browser": p.add_argument("-b", "--browser", default=None, help="Define browser used by python webbrowser. " "See https://docs.python.org/2/library/webbrowser.html#webbrowser.register") elif arg == "force": p.add_argument("-f", '--force', default=False, action="store_true", help="Overwrite pre-existent files without prompting for confirmation.") else: raise ValueError("Invalid arg: %s" % arg) # Subparser for structure command. p_structure = subparsers.add_parser('structure', parents=[copts_parser], help=abiview_structure.__doc__) p_structure.add_argument("-a", "--appname", nargs="?", type=str, default="vesta", help=("Application name. Default: vesta. " "Possible options: %s, mayavi, vtk" % ", ".join(Visualizer.all_visunames()))) # Subparser for hist command. p_hist = subparsers.add_parser('hist', parents=[copts_parser], help=abiview_hist.__doc__) p_hist.add_argument("-a", "--appname", nargs="?", default=None, const="ovito", help=("Application name. Default: ovito. " "Possible options: `%s`, `mpl` (matplotlib) `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) p_hist.add_argument("--xdatcar", default=False, action="store_true", help="Convert HIST file into XDATCAR format.") add_args(p_hist, "force") # Subparser for data command. p_data = subparsers.add_parser('data', parents=[copts_parser], help=abiview_data.__doc__) p_data.add_argument("-i", "--use-index", default=False, action="store_true", help="Use the row index as x-value in the plot. By default the plotter uses the first column as x-values") # Subparser for abo command. p_abo = subparsers.add_parser('abo', parents=[copts_parser], help=abiview_abo.__doc__) # Subparser for log command. p_log = subparsers.add_parser('log', parents=[copts_parser], help=abiview_log.__doc__) # Subparser for log command. p_dirviz = subparsers.add_parser('dirviz', parents=[copts_parser], help=abiview_dirviz.__doc__) p_dirviz.add_argument("-e", "--engine", type=str, default="fdp", help=("graphviz engine: ['dot', 'neato', 'twopi', 'circo', 'fdp', 'sfdp', 'patchwork', 'osage']. " "See http://www.graphviz.org/pdf/dot.1.pdf " "Use `conda install python-graphviz` or `pip install graphviz` to install the python package")) # Subparser for ebands commands. p_ebands = subparsers.add_parser('ebands', parents=[copts_parser, slide_parser], help=abiview_ebands.__doc__) add_args(p_ebands, "xmgrace", "bxsf", "force") # Subparser for fatbands commands. p_fatbands = subparsers.add_parser('fatbands', parents=[copts_parser, slide_parser], help=abiview_fatbands.__doc__) # Subparser for ddb command. p_ddb = subparsers.add_parser('ddb', parents=[copts_parser, slide_parser], help=abiview_ddb.__doc__) add_args(p_ddb, "xmgrace", "phononweb", "browser", "force") # Subparser for phbands command. p_phbands = subparsers.add_parser('phbands', parents=[copts_parser, slide_parser], help=abiview_phbands.__doc__) add_args(p_phbands, "xmgrace", "phononweb", "browser", "force") # Subparser for phdos command. p_phdos = subparsers.add_parser('phdos', parents=[copts_parser, slide_parser], help=abiview_phdos.__doc__) # Subparser for gruns command. p_gruns = subparsers.add_parser('gruns', parents=[copts_parser, slide_parser], help=abiview_gruns.__doc__) # Subparser for scr command. p_scr = subparsers.add_parser('scr', parents=[copts_parser, slide_parser], help=abiview_scr.__doc__) # Subparser for sigres command. p_sigres = subparsers.add_parser('sigres', parents=[copts_parser, slide_parser], help=abiview_sigres.__doc__) # Subparser for mdf command. p_mdf = subparsers.add_parser('mdf', parents=[copts_parser, slide_parser], help=abiview_mdf.__doc__) # Subparser for optic command. p_optic = subparsers.add_parser('optic', parents=[copts_parser, slide_parser], help=abiview_optic.__doc__) # Subparser for a2f command. p_a2f = subparsers.add_parser('a2f', parents=[copts_parser, slide_parser], help=abiview_a2f.__doc__) # Subparser for sigeph command. p_sigeph = subparsers.add_parser('sigeph', parents=[copts_parser, slide_parser], help=abiview_sigeph.__doc__) # Subparser for denpot command. #p_denpot = subparsers.add_parser('denpot', parents=[copts_parser], help=abiview_denpot.__doc__) #p_denpot.add_argument("-a", "--appname", nargs="?", default=None, const="vesta", # help=("Application name. Default: vesta. " # "Possible options: `%s`, `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) #p_denpot.add_argument("--chgcar", default=False, action="store_true", "Convert Density to CHGCAR format.") #p_denpot.add_argument("--cube", default=False, action="store_true", "Convert Density/Potential to CUBE format.") return parser
def get_parser(with_epilog=False): # 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 (Abinit Netcdf files, CIF, Abinit input/output files, POSCAR ...)" ) # Parent parser for commands supporting (jupyter notebooks) nb_parser = argparse.ArgumentParser(add_help=False) nb_parser.add_argument('-nb', '--notebook', default=False, action="store_true", help='Generate jupyter notebook.') nb_parser.add_argument('--foreground', action='store_true', default=False, help="Run jupyter notebook in the foreground.") parser = argparse.ArgumentParser( epilog=get_epilog() if with_epilog else "", formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', 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" ) spgopt_parser.add_argument("--no-time-reversal", default=False, action="store_true", help="Don't use time-reversal.") # 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" ) # Parent parser for commands that need to save structure to file. savefile_parser = argparse.ArgumentParser(add_help=False) savefile_parser.add_argument( "-s", "--savefile", default="", type=str, help= "Save final structure to file. Format is detected from file extensions " "e.g. out.abi for Abinit input, out.cif for CIF format.") # Helper functions to construct sub-parsers. def add_primitive_options(parser): """Add --no-primitive and --primitive-standard options to a parser.""" group = parser.add_mutually_exclusive_group() group.add_argument('--no-primitive', default=False, action='store_true', help="Do not enforce primitive cell.") group.add_argument('--primitive-standard', default=False, action='store_true', help="Enforce primitive standard cell.") supported_formats = "(abivars, cif, xsf, poscar, qe, cssr, json, None)" def add_format_arg(parser, default, option=True): """Add --format option to a parser with default value `default`.""" if option: parser.add_argument("-f", "--format", default=default, type=str, help="Output format. Default: %s. Accept: %s" % (default, supported_formats)) else: parser.add_argument('format', nargs="?", default=default, type=str, help="Output format. Default: %s. Accept: %s" % (default, supported_formats)) # 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") # Subparser for spglib command. p_spglib = subparsers.add_parser( 'spglib', parents=[copts_parser, path_selector, spgopt_parser], help="Analyze structure with spglib.") # Subparser for abispg command. p_abispg = subparsers.add_parser( 'abispg', parents=[copts_parser, path_selector, savefile_parser], help="Extract/Compute Abinit space group from file with structure.") p_abispg.add_argument("-t", "--tolsym", type=float, default=None, help="""\ Gives the tolerance on the atomic positions (reduced coordinates), primitive vectors, or magnetization, to be considered equivalent, thanks to symmetry operations. This is used in the recognition of the set of symmetries of the system, or the application of the symmetry operations to generate from a reduced set of atoms, the full set of atoms. Note that a value larger than 0.01 is considered to be unacceptable.""" ) p_abispg.add_argument("-d", "--diff-mode", type=str, default="table", choices=["table", "diff"], help="Select diff output format.") # Subparser for convert command. p_convert = subparsers.add_parser( 'convert', parents=[copts_parser, path_selector], help="Convert structure to the specified format.") add_format_arg(p_convert, default="cif") # Subparser for supercell command. p_supercell = subparsers.add_parser('supercell', parents=[copts_parser, path_selector], help="Generate supercell.") p_supercell.add_argument("-s", "--scaling_matrix", nargs="+", required=True, type=int, help="""\ scaling_matrix: A scaling matrix for transforming the lattice vectors. Has to be all integers. Several options are possible: a. A full 3x3 scaling matrix defining the linear combination the old lattice vectors. E.g., -s 2,1,0 0,3,0, 0,0,1 generates a new structure with lattice vectors a' = 2a + b, b' = 3b, c' = c where a, b, and c are the lattice vectors of the original structure. b. An sequence of three scaling factors. E.g., -s 2, 1, 1 specifies that the supercell should have dimensions 2a x b x c. c. A number, which simply scales all lattice vectors by the same factor. """) add_format_arg(p_supercell, default="abivars") # Subparser for abisanitize p_abisanitize = subparsers.add_parser( 'abisanitize', parents=[copts_parser, path_selector, spgopt_parser, savefile_parser], help= "Sanitize structure with abi_sanitize, compare structures and save result to file." ) add_primitive_options(p_abisanitize) # Subparser for irefine p_irefine = subparsers.add_parser( 'irefine', parents=[copts_parser, path_selector, spgopt_parser], help= "Refine structure with abi_sanitize iteratively, stop if target space group is obtained." ) p_irefine.add_argument("--target-spgnum", required=True, type=int, help="Target space group number.") p_irefine.add_argument("--symprec-step", default=0.05, type=float, help='Increment for symprec.') p_irefine.add_argument("--angle-tolerance-step", default=0.0, type=float, help='Increment for angle_tolerance.') p_irefine.add_argument("--ntrial", default=50, type=int, help='Number of trials. Default 50.') add_primitive_options(p_irefine) # Subparser for conventional. p_conventional = subparsers.add_parser( 'conventional', parents=[copts_parser, path_selector, spgopt_parser, savefile_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") # Subparser for neighbors. p_neighbors = subparsers.add_parser( 'neighbors', parents=[copts_parser, path_selector], help= "Get neighbors for each atom in the unit cell, out to a distance radius." ) p_neighbors.add_argument("-r", "--radius", default=2, type=float, help="Radius of the sphere in Angstrom.") # Subparser for interpolate. p_interpolate = subparsers.add_parser( 'interpolate', parents=[copts_parser], help= ("Interpolate between two structures. Useful for the construction of NEB inputs." )) p_interpolate.add_argument("filepaths", nargs=2, help="Files with initial and final structures.") p_interpolate.add_argument( "-n", "--nimages", default=10, type=int, help="No. of interpolation images. Defaults to 10.") p_interpolate.add_argument("--autosort_tol", default=0.5, type=float, help="""\ A distance tolerance in Angstrom in which to automatically sort end_structure to match to the closest points in this particular structure. This is usually what you want in a NEB calculation. 0 implies no sorting. Otherwise, a 0.5 value (default) usually works pretty well.""" ) add_format_arg(p_interpolate, default="abivars") # Subparser for xrd. p_xrd = subparsers.add_parser('xrd', parents=[copts_parser, path_selector], help="X-ray diffraction plot.") p_xrd.add_argument( "-w", "--wavelength", default="CuKa", type=str, help= ("The wavelength can be specified as a string. It must be one of the " "supported definitions in the WAVELENGTHS dict declared in pymatgen/analysis/diffraction/xrd.py." "Defaults to 'CuKa', i.e, Cu K_alpha radiation.")) p_xrd.add_argument( "-s", "--symprec", default=0, type=float, help= ("Symmetry precision for structure refinement. " "If set to 0, no refinement is done. Otherwise, refinement is performed using spglib with provided precision." )) p_xrd.add_argument( "-t", "--two-theta-range", default=(0, 90), nargs=2, help= ("Tuple for range of two_thetas to calculate in degrees. Defaults to (0, 90)." )) p_xrd.add_argument( "-nap", "--no-annotate-peaks", default=False, action="store_true", help="Whether to annotate the peaks with plane information.") # Subparser for oxistate. p_oxistate = subparsers.add_parser( 'oxistate', parents=[copts_parser, path_selector], help="Estimate oxidation states with pymatgen bond valence analysis.") # Subparser for ipython. p_ipython = subparsers.add_parser( 'ipython', parents=[copts_parser, path_selector], help="Open IPython shell for advanced operations on structure object.") # Subparser for notebook. 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.") # Subparser for ngkpt. p_ngkpt = subparsers.add_parser( 'ngkpt', parents=[copts_parser, path_selector], help="Return the Abinit k-point sampling variables " "from the number of divisions used to sample the smallest " "lattice vector of the reciprocal lattice.") p_ngkpt.add_argument( "-n", "--nksmall", required=True, type=int, help= "Number of divisions used to sample the smallest reciprocal lattice vector." ) # Subparser for ktables. p_ktables = subparsers.add_parser( 'ktables', 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_ktables.add_argument("-m", "--mesh", nargs=3, required=True, type=int, help="Mesh divisions e.g. 2 3 4") p_ktables.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: Unshifted mesh.")) p_ktables.add_argument("--no-time-reversal", default=False, action="store_true", help="Don't use time-reversal.") # Subparser for abikmesh. p_abikmesh = subparsers.add_parser( 'abikmesh', parents=[copts_parser, path_selector], help= ("Read structure from file, call Abinit to sample the BZ with ngkpt, shiftk, and kptopt. " "Print k-points in the IBZ with weights.")) p_abikmesh.add_argument( "--kppa", default=None, type=int, help= "Number of k-points per reciprocal atom. Mutually exclusive with ngkpt." ) p_abikmesh.add_argument("--ngkpt", nargs=3, default=None, type=int, help="Mesh divisions e.g. 2 3 4") p_abikmesh.add_argument("--shiftk", nargs="+", default=(0.5, 0.5, 0.5), type=float, help="Kmesh shifts. Default: 0.5 0.5 0.5") p_abikmesh.add_argument("--kptopt", default=1, type=int, help="Kptopt input variable. Default: 1") # Subparser for kmesh_jhu. #p_kmesh_jhu = subparsers.add_parser('kmesh_jhu', parents=[copts_parser, path_selector], help="Foobar ") # Subparser for lgk. p_lgk = subparsers.add_parser( 'lgk', parents=[copts_parser, path_selector, spgopt_parser], help= "Read structure from file, find little group of k-point, print Bilbao character table." ) p_lgk.add_argument("-k", "--kpoint", nargs=3, required=True, type=float, help="K-point in reduced coordinates e.g. 0.25 0 0") # Subparser for kstar. p_kstar = subparsers.add_parser( 'kstar', parents=[copts_parser, path_selector, spgopt_parser], help="Read structure from file, print star of k-point.") p_kstar.add_argument("-k", "--kpoint", nargs=3, required=True, type=float, help="K-point in reduced coordinates e.g. 0.25 0 0") # Subparser for visualize command. p_visualize = subparsers.add_parser( 'visualize', parents=[copts_parser, path_selector], help=( "Visualize the structure with the specified application. " "Requires external app or optional python modules (mayavi, vtk).")) p_visualize.add_argument( "-a", "--appname", type=str, default="vesta", help= ("Application name. Possible options: %s, mpl (matplotlib), mayavi, vtk" % ", ".join(Visualizer.all_visunames()))) # Options for commands accessing the materials project database. mp_rest_parser = argparse.ArgumentParser(add_help=False) mp_rest_parser.add_argument( "--mapi-key", default=None, help="Pymatgen MAPI_KEY. Use value in .pmgrc.yaml if not specified.") mp_rest_parser.add_argument( "--endpoint", help="Pymatgen database.", default="https://www.materialsproject.org/rest/v2") mp_rest_parser.add_argument( "-b", "--browser", default=False, action='store_true', help="Open materials-project webpages in browser") # Subparser for mp_id command. p_mpid = subparsers.add_parser( 'mp_id', parents=[copts_parser, mp_rest_parser], help= "Get structure from the pymatgen database. Export to format. Requires internet connection and MAPI_KEY." ) p_mpid.add_argument("mpid", type=str, default=None, help="Pymatgen identifier.") add_format_arg(p_mpid, default="cif") # Subparser for mp_match command. p_mpmatch = subparsers.add_parser( 'mp_match', parents=[path_selector, mp_rest_parser, copts_parser, nb_parser], help= "Get structure from the pymatgen database. Requires internet connection and PMG_MAPI_KEY." ) add_format_arg(p_mpmatch, default="abivars") # Subparser for mp_search command. p_mpsearch = subparsers.add_parser( 'mp_search', parents=[mp_rest_parser, copts_parser, nb_parser], help= "Get structure from the pymatgen database. Requires internet connection and PMG_MAPI_KEY" ) p_mpsearch.add_argument( "chemsys_formula_id", type=str, default=None, help= "A chemical system (e.g., Li-Fe-O), or formula (e.g., Fe2O3) or materials_id (e.g., mp-1234)." ) p_mpsearch.add_argument( "-s", "--select-spgnum", type=int, default=None, help="Select structures with this space group number.") add_format_arg(p_mpsearch, default="abivars") # Subparser for mp_pd command. p_mp_pda = subparsers.add_parser( 'mp_pd', parents=[mp_rest_parser, copts_parser], help=( "Generate phase diagram with entries from the Materials Project. " "Requires internet connection and PMG_MAPI_KEY")) p_mp_pda.add_argument( "file_or_elements", type=str, default=None, help="FILE with structure or elements e.g., Li-Fe-O).") p_mp_pda.add_argument("-u", "--show-unstable", type=int, default=0, help="""Whether unstable phases will be plotted as well as red crosses. If a number > 0 is entered, all phases with ehull < show_unstable will be shown.""") # Subparser for cod_search command. p_codsearch = subparsers.add_parser( 'cod_search', parents=[copts_parser, nb_parser], help= "Get structure from COD database. Requires internet connection and mysql" ) p_codsearch.add_argument("formula", type=str, default=None, help="formula (e.g., Fe2O3).") p_codsearch.add_argument( "-s", "--select-spgnum", type=int, default=None, help="Select structures with this space group number.") p_codsearch.add_argument('--primitive', default=False, action='store_true', help="Convert COD cells into primitive cells.") add_format_arg(p_codsearch, default="abivars") # Subparser for cod_id command. p_codid = subparsers.add_parser( 'cod_id', parents=[copts_parser], help= "Get structure from COD database. Requires internet connection and mysql" ) p_codid.add_argument("cod_identifier", type=int, default=None, help="COD identifier.") p_codid.add_argument('--primitive', default=False, action='store_true', help="Convert COD cell into primitive cell.") add_format_arg(p_codid, default="abivars") # Subparser for animate command. p_animate = subparsers.add_parser( 'animate', parents=[copts_parser, path_selector], help= "Read structures from HIST.nc or XDATCAR. Print structures in Xrysden AXSF format to stdout." ) return parser
def get_parser(with_epilog=False): # Parent parser for common options. copts_parser = argparse.ArgumentParser(add_help=False) copts_parser.add_argument('filepath', type=str, help="File to visualize.") copts_parser.add_argument('--loglevel', default="ERROR", type=str, help="Set the loglevel. Possible values: CRITICAL, ERROR (default), WARNING, INFO, DEBUG") 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('--seaborn', action="store_true", help="Use seaborn settings.") copts_parser.add_argument('-mpl', "--mpl-backend", default=None, help=("Set matplotlib interactive backend. " "Possible values: GTKAgg, GTK3Agg, GTK, GTKCairo, GTK3Cairo, WXAgg, WX, TkAgg, Qt4Agg, Qt5Agg, macosx." "See also: https://matplotlib.org/faq/usage_faq.html#what-is-a-backend.")) # Parent parser for commands supporting MplExpose. slide_parser = argparse.ArgumentParser(add_help=False) slide_parser.add_argument("-s", "--slide-mode", default=False, action="store_true", help="Iterate over figures. Expose all figures at once if not given on the CLI.") slide_parser.add_argument("-t", "--slide-timeout", type=int, default=None, help="Close figure after slide-timeout seconds (only if slide-mode). Block if not specified.") # Build the main parser. parser = argparse.ArgumentParser(epilog=get_epilog() if with_epilog else "", formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version=abilab.__version__) # Create the parsers for the sub-commands subparsers = parser.add_subparsers(dest='command', help='sub-command help', description="Valid subcommands") def add_args(p, *args): """Add arguments to subparser `p`.""" for arg in args: if arg == "xmgrace": p.add_argument('--xmgrace', default=False, action="store_true", help="Print bands in xmgrace format to stdout and exit.") elif arg == "bxsf": p.add_argument('--bxsf', default=False, action="store_true", help=("Generate BXSF file suitable for the visualization of isosurfaces with Xcrysden" "(xcrysden --bxsf FILE).\n Requires k-points in IBZ. Print to stdout and exit.")) elif arg == "phononweb": p.add_argument("-web", "--phononwebsite", default=False, action="store_true", help=("Visualize phonon band structure on the phononwebsite. " "http://henriquemiranda.github.io/phononwebsite/")) elif arg == "browser": p.add_argument("-b", "--browser", default=None, help="Define browser used by python webbrowser. " "See https://docs.python.org/2/library/webbrowser.html#webbrowser.register") elif arg == "force": p.add_argument("-f", '--force', default=False, action="store_true", help="Overwrite pre-existent files without prompting for confirmation.") else: raise ValueError("Invalid arg: %s" % arg) # Subparser for structure command. p_structure = subparsers.add_parser('structure', parents=[copts_parser], help=abiview_structure.__doc__) p_structure.add_argument("-a", "--appname", nargs="?", type=str, default="vesta", help=("Application name. Default: vesta. " "Possible options: %s, mayavi, vtk" % ", ".join(Visualizer.all_visunames()))) # Subparser for hist command. p_hist = subparsers.add_parser('hist', parents=[copts_parser], help=abiview_hist.__doc__) p_hist.add_argument("-a", "--appname", nargs="?", default=None, const="ovito", help=("Application name. Default: ovito. " "Possible options: `%s`, `mpl` (matplotlib) `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) p_hist.add_argument("--xdatcar", default=False, action="store_true", help="Convert HIST file into XDATCAR format.") add_args(p_hist, "force") # Subparser for abo command. p_abo = subparsers.add_parser('abo', parents=[copts_parser], help=abiview_abo.__doc__) # Subparser for log command. p_log = subparsers.add_parser('log', parents=[copts_parser], help=abiview_log.__doc__) # Subparser for log command. p_dirviz = subparsers.add_parser('dirviz', parents=[copts_parser], help=abiview_dirviz.__doc__) p_dirviz.add_argument("-e", "--engine", type=str, default="fdp", help=("graphviz engine: ['dot', 'neato', 'twopi', 'circo', 'fdp', 'sfdp', 'patchwork', 'osage']. " "See http://www.graphviz.org/pdf/dot.1.pdf " "Use `conda install python-graphviz` or `pip install graphviz` to install the python package")) # Subparser for ebands commands. p_ebands = subparsers.add_parser('ebands', parents=[copts_parser, slide_parser], help=abiview_ebands.__doc__) add_args(p_ebands, "xmgrace", "bxsf", "force") # Subparser for fatbands commands. p_fatbands = subparsers.add_parser('fatbands', parents=[copts_parser, slide_parser], help=abiview_fatbands.__doc__) # Subparser for ddb command. p_ddb = subparsers.add_parser('ddb', parents=[copts_parser, slide_parser], help=abiview_ddb.__doc__) add_args(p_ddb, "xmgrace", "phononweb", "browser", "force") # Subparser for phbands command. p_phbands = subparsers.add_parser('phbands', parents=[copts_parser, slide_parser], help=abiview_phbands.__doc__) add_args(p_phbands, "xmgrace", "phononweb", "browser", "force") # Subparser for phdos command. p_phdos = subparsers.add_parser('phdos', parents=[copts_parser, slide_parser], help=abiview_phdos.__doc__) # Subparser for gruns command. p_gruns = subparsers.add_parser('gruns', parents=[copts_parser, slide_parser], help=abiview_gruns.__doc__) # Subparser for scr command. p_scr = subparsers.add_parser('scr', parents=[copts_parser, slide_parser], help=abiview_scr.__doc__) # Subparser for sigres command. p_sigres = subparsers.add_parser('sigres', parents=[copts_parser, slide_parser], help=abiview_sigres.__doc__) # Subparser for mdf command. p_mdf = subparsers.add_parser('mdf', parents=[copts_parser, slide_parser], help=abiview_mdf.__doc__) # Subparser for optic command. p_optic = subparsers.add_parser('optic', parents=[copts_parser, slide_parser], help=abiview_optic.__doc__) # Subparser for a2f command. p_a2f = subparsers.add_parser('a2f', parents=[copts_parser, slide_parser], help=abiview_a2f.__doc__) # Subparser for sigeph command. p_sigeph = subparsers.add_parser('sigeph', parents=[copts_parser, slide_parser], help=abiview_sigeph.__doc__) # Subparser for denpot command. #p_denpot = subparsers.add_parser('denpot', parents=[copts_parser], help=abiview_denpot.__doc__) #p_denpot.add_argument("-a", "--appname", nargs="?", default=None, const="vesta", # help=("Application name. Default: vesta. " # "Possible options: `%s`, `mayavi`, `vtk`" % ", ".join(Visualizer.all_visunames()))) #p_denpot.add_argument("--chgcar", default=False, action="store_true", "Convert Density to CHGCAR format.") #p_denpot.add_argument("--cube", default=False, action="store_true", "Convert Density/Potential to CUBE format.") return parser
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. abistrcut.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 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 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.") # Subparser for bz. p_bz = subparsers.add_parser('bz', parents=[copts_parser, path_selector], help="Read structure from file, plot Brillouin zone with matplotlib.") # Subparser for bz. 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 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 env variable if not specified.") p_pmgdata.add_argument("--endpoint", default="www.materialsproject.org", help="Pymatgen database.") # 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 == "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 == "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": from abipy.iotools import xsf_write_structure 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: from pymatgen.io.vaspio import Xdatcar 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 main(): def str_examples(): examples = """\ Usage example:\n 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. abistrctu.py convert out_HIST abivars => Read the last structure from the HIST file and print the corresponding Abinit variables. abistruct.py visualize filepath xcrysden => Visualize the structure with XcrysDen. abistruct.py pmgdata mp-149 => Get structure from pymatgen database and print its JSON representation. """ return examples 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") parser = argparse.ArgumentParser( epilog=str_examples(), formatter_class=argparse.RawDescriptionHelpFormatter) # 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") subparsers.add_parser('version', help='Show version number and exit') # Subparser for convert command. p_convert = subparsers.add_parser( 'convert', parents=[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).") # Subparser for visualize command. p_visualize = subparsers.add_parser( 'visualize', parents=[path_selector], help="Visualize the structure with the specified visualizer") p_visualize.add_argument('visualizer', nargs="?", default="xcrysden", type=str, help=("Visualizer name. " "List of visualizer supported: %s" % ", ".join(Visualizer.all_visunames()))) # Subparser for pmgid command. p_pmgdata = subparsers.add_parser( 'pmgdata', 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 env variable if not specified.") p_pmgdata.add_argument("--host", default="www.materialsproject.org", help="Pymatgen database.") # Subparser for animate command. p_animate = subparsers.add_parser( 'animate', parents=[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: show_examples_and_exit(error_code=1) if options.command == "version": from abipy.core.release import version print(version) return 0 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 == "visualize": structure = abilab.Structure.from_file(options.filepath) structure.visualize(options.visualizer) 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, host=options.host) # Convert to json and print it. s = structure.convert(format="json") #s = structure.convert(format="mson") print(s) elif options.command == "animate": from abipy.iotools import xsf_write_structure 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: from pymatgen.io.vaspio import Xdatcar structures = Xdatcar(filepath).structures if not structures: raise RuntimError( "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