#!/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))