Source code for pymatgen.cli.pmg_config

#!/usr/bin/env python
# coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

"""
Implementation for `pmg config` CLI.
"""


import os
import sys
import glob
import shutil
import subprocess
from monty.serialization import loadfn, dumpfn

from pymatgen import SETTINGS_FILE
from urllib.request import urlretrieve


[docs]def setup_potcars(args): """ Setup POTCAR directirt, :param args: args from command. """ pspdir, targetdir = [os.path.abspath(d) for d in args.potcar_dirs] try: os.makedirs(targetdir) except OSError: r = input("Destination directory exists. Continue (y/n)? ") if r != "y": print("Exiting ...") sys.exit(0) print("Generating pymatgen resources directory...") name_mappings = { "potpaw_PBE": "POT_GGA_PAW_PBE", "potpaw_PBE_52": "POT_GGA_PAW_PBE_52", "potpaw_PBE_54": "POT_GGA_PAW_PBE_54", "potpaw_PBE.52": "POT_GGA_PAW_PBE_52", "potpaw_PBE.54": "POT_GGA_PAW_PBE_54", "potpaw_LDA": "POT_LDA_PAW", "potpaw_LDA.52": "POT_LDA_PAW_52", "potpaw_LDA.54": "POT_LDA_PAW_54", "potpaw_LDA_52": "POT_LDA_PAW_52", "potpaw_LDA_54": "POT_LDA_PAW_54", "potUSPP_LDA": "POT_LDA_US", "potpaw_GGA": "POT_GGA_PAW_PW91", "potUSPP_GGA": "POT_GGA_US_PW91" } for (parent, subdirs, files) in os.walk(pspdir): basename = os.path.basename(parent) basename = name_mappings.get(basename, basename) for subdir in subdirs: filenames = glob.glob(os.path.join(parent, subdir, "POTCAR*")) if len(filenames) > 0: try: basedir = os.path.join(targetdir, basename) if not os.path.exists(basedir): os.makedirs(basedir) fname = filenames[0] dest = os.path.join(basedir, os.path.basename(fname)) shutil.copy(fname, dest) ext = fname.split(".")[-1] if ext.upper() in ["Z", "GZ"]: subprocess.Popen(["gunzip", dest]).communicate() elif ext.upper() in ["BZ2"]: subprocess.Popen(["bunzip2", dest]).communicate() if subdir == "Osmium": subdir = "Os" dest = os.path.join(basedir, "POTCAR.{}".format(subdir)) shutil.move(os.path.join(basedir, "POTCAR"), dest) subprocess.Popen(["gzip", "-f", dest]).communicate() except Exception as ex: print("An error has occured. Message is %s. Trying to " "continue... " % str(ex)) print("") print("PSP resources directory generated. It is recommended that you " "run 'pmg config --add PMG_VASP_PSP_DIR %s'" % os.path.abspath(targetdir)) print("Start a new terminal to ensure that your environment variables " "are properly set.")
[docs]def build_enum(fortran_command="gfortran"): """ Build enum. :param fortran_command: """ currdir = os.getcwd() state = True try: subprocess.call(["git", "clone", "--recursive", "https://github.com/msg-byu/enumlib.git"]) os.chdir(os.path.join(currdir, "enumlib", "symlib", "src")) os.environ["F90"] = fortran_command subprocess.call(["make"]) enumpath = os.path.join(currdir, "enumlib", "src") os.chdir(enumpath) subprocess.call(["make"]) for f in ["enum.x", "makestr.x"]: subprocess.call(["make", f]) shutil.copy(f, os.path.join("..", "..")) except Exception as ex: print(str(ex)) state = False finally: os.chdir(currdir) shutil.rmtree("enumlib") return state
[docs]def build_bader(fortran_command="gfortran"): """ Build bader package. :param fortran_command: """ bader_url = "http://theory.cm.utexas.edu/henkelman/code/bader/download/bader.tar.gz" currdir = os.getcwd() state = True try: urlretrieve(bader_url, "bader.tar.gz") subprocess.call(["tar", "-zxf", "bader.tar.gz"]) os.chdir("bader") subprocess.call( ["cp", "makefile.osx_" + fortran_command, "makefile"]) subprocess.call(["make"]) shutil.copy("bader", os.path.join("..", "bader_exe")) os.chdir("..") shutil.rmtree("bader") os.remove("bader.tar.gz") shutil.move("bader_exe", "bader") except Exception as ex: print(str(ex)) state = False finally: os.chdir(currdir) return state
[docs]def install_software(args): """ Install all optional external software. :param args: """ try: subprocess.call(["ifort", "--version"]) print("Found ifort") fortran_command = "ifort" except Exception: try: subprocess.call(["gfortran", "--version"]) print("Found gfortran") fortran_command = "gfortran" except Exception as ex: print(str(ex)) print("No fortran compiler found.") sys.exit(-1) enum = None bader = None if args.install == "enumlib": print("Building enumlib") enum = build_enum(fortran_command) print("") elif args.install == "bader": print("Building bader") bader = build_bader(fortran_command) print("") if bader or enum: print("Please add {} to your PATH or move the executables multinum.x, " "makestr.x and/or bader to a location in your PATH." .format(os.path.abspath("."))) print("")
[docs]def add_config_var(args): """ Add configuration args. :param args: """ d = {} if os.path.exists(SETTINGS_FILE): shutil.copy(SETTINGS_FILE, SETTINGS_FILE + ".bak") print("Existing %s backed up to %s" % (SETTINGS_FILE, SETTINGS_FILE + ".bak")) d = loadfn(SETTINGS_FILE) toks = args.var_spec if len(toks) % 2 != 0: print("Bad variable specification!") sys.exit(-1) for i in range(int(len(toks) / 2)): d[toks[2 * i]] = toks[2 * i + 1] dumpfn(d, SETTINGS_FILE, default_flow_style=False) print("New %s written!" % (SETTINGS_FILE))
[docs]def configure_pmg(args): """ Handle configure command. :param args: """ if args.potcar_dirs: setup_potcars(args) elif args.install: install_software(args) elif args.var_spec: add_config_var(args)