Source code for abipy.scripts.abidoc

#!/usr/bin/env python
"""
Interface to the database of ABINIT input variables
"""
from __future__ import annotations

import sys
import argparse
import abipy.flowtk as flowtk

from monty.functools import prof_main
from monty.termcolor import cprint
from abipy.core.release import __version__
from abipy import abilab






[docs] def get_epilog() -> str: return """\ Usage example: abidoc.py man ecut --> Show documentation for ecut input variable. abidoc.py graphviz acell --> Draw parents and children of variable with graphviz package. abidoc.py browse acell --> Open url in external browser. abidoc.py apropos ecut --> To search in the database for the variables related to ecut. abidoc.py find paw --> To search in the database for the variables whose name contains paw. abidoc.py list --> Print full list of variables. abidoc.py withdim natom --> Print arrays depending on natom. abidoc.py scheduler --> Document scheduler options. abidoc.py manager --> Document manager options. Use `abidoc.py --help` for help and `abidoc.py COMMAND --help` to get the documentation for `COMMAND`. Use `-v` to increase verbosity level (can be supplied multiple times e.g -vv). """
[docs] def get_parser(with_epilog=False): # 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=__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") copts_parser.add_argument("-c", '--codename', type=str, default="abinit", help="Code name e.g. anaddb, optic... Default: abinit") var_parser = argparse.ArgumentParser(add_help=False) var_parser.add_argument('varname', help="ABINIT variable") # Create the parsers for the sub-commands subparsers = parser.add_subparsers(dest='command', help='sub-command help', description="Valid subcommands") # Subparser for man. p_man = subparsers.add_parser('man', parents=[copts_parser, var_parser], help="Show documentation for varname.") # Subparser for graphviz. p_graphviz = subparsers.add_parser('graphviz', parents=[copts_parser, var_parser], help=("Draw variable dependencies with graphviz package." "See https://graphviz.readthedocs.io/.")) p_graphviz.add_argument("-e", "--engine", type=str, default="automatic", help=("graphviz engine: ['dot', 'neato', 'twopi', 'circo', 'fdp', 'sfdp', 'patchwork', 'osage']. " "Default: automatic i.e. the engine is automatically selected. 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 browse. p_browse = subparsers.add_parser('browse', parents=[copts_parser, var_parser], help="Open documentation in browser.") # Subparser for apropos. p_apropos = subparsers.add_parser('apropos', parents=[copts_parser, var_parser], help="Find variables related to varname.") # Subparser for find. p_find = subparsers.add_parser('find', parents=[copts_parser, var_parser], help="Find all variables whose name contains varname.") # Subparser for require. #p_require = subparsers.add_parser('require', parents=[copts_parser], help="Find all variables required by varname.") # Subparser for withdim. p_withdim = subparsers.add_parser('withdim', parents=[copts_parser], help="Find all arrays depending on the given dimension.") p_withdim.add_argument("dimname", help="Dimension name") # Subparser for list. p_list = subparsers.add_parser('list', parents=[copts_parser], help="List all variables.") p_list.add_argument('--mode', default="a", help="Sort mode, `a` for alphabethical, `s` for varset, `c` for characteristics.") # Subparser for manager. p_manager = subparsers.add_parser('manager', parents=[copts_parser], help="Document the TaskManager options.") p_manager.add_argument("qtype", nargs="?", default=None, help=("Write job script to terminal if qtype='script' else " "document the qparams for the given QueueAdapter qtype e.g. slurm.")) # Subparser for scheduler p_docsched = subparsers.add_parser('scheduler', parents=[copts_parser], help="Document the options available in scheduler.yml.") # Subparser for abibuild p_abibuild = subparsers.add_parser('abibuild', parents=[copts_parser], help="Show ABINIT build information and exit.") # Subparser for links p_urls = subparsers.add_parser('urls', parents=[copts_parser], help="Produce Yaml file with varname --> ulrs.") return parser
[docs] @prof_main def main(): def show_examples_and_exit(err_msg=None, error_code=1): """Display the usage of the script.""" sys.stderr.write(get_epilog()) if err_msg: sys.stderr.write("Fatal Error\n" + err_msg + "\n") sys.exit(error_code) parser = get_parser(with_epilog=True) 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) # Get the dabase of variables for codename. from abipy.abio.abivar_database.variables import get_codevars codevars = get_codevars() vdb = codevars[options.codename] if options.command == "man": abilab.abinit_help(options.varname) elif options.command == "browse": return vdb[options.varname].browse() elif options.command == "graphviz": if options.varname in vdb.my_varset_list: graph = vdb.get_graphviz(varset=options.varname, vartype=None, engine=options.engine) else: graph = vdb.get_graphviz_varname(varname=options.varname, engine=options.engine) import tempfile directory = tempfile.mkdtemp() print("Producing source files in:", directory) graph.view(directory=directory, cleanup=False) elif options.command == "apropos": vlist = vdb.apropos(options.varname) print_vlist(vlist, options) elif options.command == "find": vlist = [v for v in vdb.values() if options.varname in v.name] print("Find results:\n") print_vlist(vlist, options) elif options.command == "list": if options.mode == "a": # Alphabetical for i, var in enumerate(vdb.values()): print(i, repr(var)) elif options.mode == "s": # Grouped by varset for section in vdb.my_varset_list: print(30 * "#" + " Section: " + section + " " + 30 * "#") print_vlist(vdb.vars_with_section(section), options) elif options.mode == "c": # Grouped by characteristics. for char in vdb.my_characteristics: print(30 * "#" + " Characteristic: " + char + 30 * "#") print_vlist(vdb.vars_with_char(char), options) else: raise ValueError("Wrong mode %s" % options.mode) elif options.command == "withdim": for var in vdb.values(): if var.depends_on_dimension(options.dimname): cprint(repr(var), "yellow") print("dimensions:", str(var.dimensions), "\n") elif options.command == "scheduler": print("Options that can be specified in scheduler.yml:") print(flowtk.PyFlowScheduler.autodoc()) return 0 elif options.command == "manager": # Document TaskManager options and qparams. qtype = options.qtype if qtype == "script": manager = flowtk.TaskManager.from_user_config() script = manager.qadapter.get_script_str( job_name="job_name", launch_dir="workdir", executable="executable", qout_path="qout_file.path", qerr_path="qerr_file.path", stdin="stdin", stdout="stdout", stderr="stderr") print(script) else: print(flowtk.TaskManager.autodoc()) print("qtype supported: %s" % flowtk.all_qtypes()) print("Use:\n\n\tabidoc.py manager slurm\n\nto show the list of qparams for slurm.\n") if qtype is not None: print("QPARAMS for %s" % qtype) flowtk.show_qparams(qtype) elif options.command == "abibuild": abinit_build = flowtk.AbinitBuild() print() print(abinit_build) print() if not options.verbose: print("Use --verbose for additional info") else: print(abinit_build.info) elif options.command == "urls": d = {} for codename in sorted(codevars.keys()): variables = codevars[codename] for varname, var in variables.items(): key = var.abivarname key.replace("@", "_") d[key] = f"[{var.name}]({var.website_url})" from ruamel.yaml import YAML YAML().dump(d, sys.stdout) else: raise ValueError("Don't know how to handle command %s" % options.command) return 0
if __name__ == "__main__": sys.exit(main())