def run_task(self, fw_spec): fw_env = fw_spec.get("_fw_env", {}) if "mpi_cmd" in fw_env: mpi_cmd = fw_spec["_fw_env"]["mpi_cmd"] elif which("mpirun"): mpi_cmd = "mpirun" elif which("aprun"): mpi_cmd = "aprun" else: raise ValueError("No MPI command found!") nproc = os.environ['PBS_NP'] v_exe = shlex.split('{} -n {} {}'.format(mpi_cmd, nproc, fw_env.get("vasp_cmd", "vasp"))) gv_exe = shlex.split('{} -n {} {}'.format(mpi_cmd, nproc, fw_env.get("gvasp_cmd", "gvasp"))) # override vasp executable in custodian jobs for job in self.jobs: job.vasp_cmd = v_exe job.gamma_vasp_cmd = gv_exe # run the custodian c = Custodian(self.handlers, self.jobs, self.max_errors) c.run() update_spec = {'prev_vasp_dir': os.getcwd(), 'prev_task_type': fw_spec['task_type']} return FWAction(update_spec=update_spec)
def run_task(self, fw_spec): # write a file containing the formula and task_type for somewhat # easier file system browsing self._write_formula_file(fw_spec) fw_env = fw_spec.get("_fw_env", {}) if "mpi_cmd" in fw_env: mpi_cmd = fw_spec["_fw_env"]["mpi_cmd"] elif which("mpirun"): mpi_cmd = "mpirun" elif which("aprun"): mpi_cmd = "aprun" else: raise ValueError("No MPI command found!") nproc = os.environ['PBS_NP'] v_exe = shlex.split('{} -n {} {}'.format(mpi_cmd, nproc, fw_env.get("vasp_cmd", "vasp"))) gv_exe = shlex.split('{} -n {} {}'.format(mpi_cmd, nproc, fw_env.get("gvasp_cmd", "gvasp"))) print 'host:', os.environ['HOSTNAME'] for job in self.jobs: job.vasp_cmd = v_exe job.gamma_vasp_cmd = gv_exe incar_errors = check_incar(fw_spec['task_type']) if incar_errors: raise ValueError("Critical error: INCAR does not pass checks: {}".format(incar_errors)) logging.basicConfig(level=logging.DEBUG) c = Custodian(self.handlers, self.jobs, max_errors=self.max_errors, gzipped_output=False, validators=[VasprunXMLValidator()]) # manual gzip custodian_out = c.run() if self.gzip_output: for f in os.listdir(os.getcwd()): if not f.lower().endswith("gz") and not f.endswith(".OU") and not f.endswith(".ER"): with open(f, 'rb') as f_in, \ GzipFile('{}.gz'.format(f), 'wb') as f_out: f_out.writelines(f_in) os.remove(f) all_errors = set() for run in custodian_out: for correction in run['corrections']: all_errors.update(correction['errors']) stored_data = {'error_list': list(all_errors)} update_spec = {'prev_vasp_dir': os.getcwd(), 'prev_task_type': fw_spec['task_type'], 'mpsnl': fw_spec['mpsnl'], 'snlgroup_id': fw_spec['snlgroup_id'], 'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters')} return FWAction(stored_data=stored_data, update_spec=update_spec)
def write_open_notebook(flow, options): """ Generate an ipython notebook and open it in the browser. Return system exit code. See also: http://nbviewer.jupyter.org/github/maxalbert/auto-exec-notebook/blob/master/how-to-programmatically-generate-and-execute-an-ipython-notebook.ipynb """ import nbformat nbf = nbformat.v4 nb = nbf.new_notebook() nb.cells.extend([ #nbf.new_markdown_cell("This is an auto-generated notebook for %s" % os.path.basename(pseudopath)), nbf.new_code_cell("""\ ##%%javascript ##IPython.OutputArea.auto_scroll_threshold = 9999; from __future__ import print_function, division, unicode_literals from abipy import abilab %matplotlib notebook import pylab pylab.rcParams['figure.figsize'] = (25.0, 10.0) import seaborn as sns"""), nbf.new_code_cell("flow = abilab.Flow.pickle_load('%s')" % flow.workdir), nbf.new_code_cell("flow.show_dependencies()"), nbf.new_code_cell("flow.check_status(show=True, verbose=0)"), nbf.new_code_cell("flow.show_inputs(nids=None, wslice=None)"), nbf.new_code_cell("flow.inspect(nids=None, wslice=None)"), nbf.new_code_cell("flow.show_abierrors()"), nbf.new_code_cell("flow.show_qouts()"), ]) # Next, we write it to a file on disk that we can then open as a new notebook. # Note: This should be as easy as: nbf.write(nb, fname), but the current api # is a little more verbose and needs a real file-like object. import tempfile, io _, nbpath = tempfile.mkstemp(suffix='.ipynb', text=True) with io.open(nbpath, 'wt', encoding="utf8") as f: nbformat.write(nb, fh) if which("jupyter") is not None: return os.system("jupyter notebook %s" % nbpath) if which("ipython") is not None: return os.system("ipython notebook %s" % nbpath) raise RuntimeError("Cannot find neither jupyther nor ipython. Install them with `pip install`")
def __init__(self, input_str, calc_type, workdir=None): super(OncvGenerator, self).__init__(workdir=workdir) self._input_str = input_str self.calc_type = calc_type calctype2exec = { "non-relativistic": which("oncvpspnr.x"), "scalar-relativistic": which("oncvpsp.x"), "fully-relativistic": which("oncvpspr.x")} self._executable = calctype2exec[calc_type] if self.executable is None: msg = "Cannot find executable for oncvpsp is PATH. Use `export PATH=dir_with_executable:$PATH`" raise RuntimeError(msg)
def __init__(self, username, hostname, workdir, sshfs_mountpoint=None): """ Args: username: Username used to login on the cluster. hostname: Name of the host. workdir: Absolute path (on the remote host) where the `AbinitFlows` will be produced. sshfs_mountpoint: Absolute path (on the local host) where the file system of the remote host will be mounted via sshfs. """ self.username, self.hostname, self.workdir = username, hostname, workdir if not os.path.isabs(self.workdir): raise ValueError("Please use an absolute path for the remote workdir") self.port = 22 # Port for SSH connection self.timeout = 30 # Timeout in seconds. self.sshfs_mountpoint = os.path.expanduser(sshfs_mountpoint) if sshfs_mountpoint else None if self.sshfs_mountpoint is not None and which("sshfs") is None: warnings.warn("Cannot locate sshfs in $PATH, cannot mount remote filesystem without SSHFS")
def has_abinit(version=None, op=">="): """ True if abinit is in $PATH. If version is not None, abinit version op version is evaluated and the result is returned. False if condition is not fulfilled or the execution of ``abinit -v`` raised CalledProcessError """ abinit = which("abinit") if abinit is None: return False if version is None: return abinit is not None try: abinit_version = str(subprocess.check_output(["abinit", "-v"])) except subprocess.CalledProcessError: # Some MPI implementations require the mpirunner. try: abinit_version = subprocess.check_output(["mpirun", "-n", "1", "abinit", "-v"]) except subprocess.CalledProcessError: try: abinit_version = subprocess.check_output(["mpiexec", "-n", "1", "abinit", "-v"]) except subprocess.CalledProcessError as exc: logger.warning(exc.output) return False return cmp_version(abinit_version, version, op=op)
def make_open_notebook(options): """ Generate an ipython notebook and open it in the browser. Return system exit code. Raise: RuntimeError if jupyther is not in $PATH """ import nbformat nbf = nbformat.v4 nb = nbf.new_notebook() nb.cells.extend([ nbf.new_markdown_cell("# This is an auto-generated notebook for %s" % os.path.relpath(filepath)), nbf.new_code_cell("""\ from __future__ import print_function, division, unicode_literals, absolute_import %matplotlib notebook #import numpy as np #import seaborn as sns from abipy import abilab\ """), nbf.new_code_cell("abifile = abilab.abiopen('%s')" % options.filepath) ]) _, nbpath = tempfile.mkstemp(suffix='.ipynb', text=True) with io.open(nbpath, 'wt', encoding="utf8") as f: nbformat.write(nb, f) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") return os.system("jupyter notebook %s" % nbpath)
def has_abinit(version, cmp=">="): """ Return True if abinit is in $PATH and version is cmp version. False if condition is not fulfilled or the execution of `abinit -v` raised CalledProcessError """ if which("abinit") is None: return False try: abiver = str(subprocess.check_output(["abinit", "-v"])) except subprocess.CalledProcessError: # Some MPI implementations require the mpirunner. try: abiver = subprocess.check_output(["mpirun", "-n", "1", "abinit", "-v"]) except subprocess.CalledProcessError: try: abiver = subprocess.check_output(["mpiexec", "-n", "1", "abinit", "-v"]) except subprocess.CalledProcessError as exc: logger.warning(exc.output) return False return {">=": abiver.strip() >= version.strip(), "==": abiver.strip() == version.strip()}[cmp]
def __init__(self): self._figures = collections.OrderedDict() self.animate_bin = which("animate") if self.animate_bin is None: raise RuntimeError("Cannot find animate executable in $PATH.\n Please install the ImageMagick suite of tools.")
def make_and_open_notebook(self, nbpath=None, foreground=False): # pragma: no cover """ Generate an jupyter_ notebook and open it in the browser. Args: nbpath: If nbpath is None, a temporay file is created. foreground: By default, jupyter is executed in background and stdout, stderr are redirected to devnull. Use foreground to run the process in foreground Return: system exit code. Raise: `RuntimeError` if jupyter_ is not in $PATH """ nbpath = self.write_notebook(nbpath=nbpath) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in $PATH. Install it with `conda install jupyter or `pip install jupyter`") if foreground: return os.system("jupyter notebook %s" % nbpath) else: fd, tmpname = tempfile.mkstemp(text=True) print(tmpname) cmd = "jupyter notebook %s" % nbpath print("Executing:", cmd) print("stdout and stderr redirected to %s" % tmpname) import subprocess process = subprocess.Popen(cmd.split(), shell=False, stdout=fd, stderr=fd) cprint("pid: %s" % str(process.pid), "yellow") return 0
def __init__(self, fft_input, executable="fftprof"): self.verbose = 1 self.fft_input = fft_input self.executable = which(executable) if self.executable is None: raise self.Error("Cannot find executable %s in $PATH" % executable)
def dojo_nbcompare(self, what="all", **kwargs): """ Generate an ipython notebook to compare the results in the dojoreport (calls dojo_compare). """ paths = [p.path for p in self] import nbformat nbf = nbformat.v4 nb = nbf.new_notebook() nb.cells.extend([ #nbf.new_markdown_cell("# This is an auto-generated notebook for %s" % os.path.basename(pseudopath)), nbf.new_code_cell("""\ from __future__ import print_function, division, unicode_literals %matplotlib notebook"""), nbf.new_code_cell("""\ from pseudo_dojo.core.pseudos import DojoTable pseudos = DojoTable(%s)""" % str(paths)), nbf.new_code_cell("pseudos.dojo_compare(what='%s')" % what), ]) _, nbpath = tempfile.mkstemp(suffix='.ipynb', text=True) import io with io.open(nbpath, 'wt', encoding="utf8") as f: nbformat.write(nb, f) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") return os.system("jupyter notebook %s" % nbpath)
def _find_loc(app_name): # Try command line version path = which(app_name) if path is not None: return path # Treat Mac OsX applications. if is_macosx(): system_apps = [f.lower() for f in os.listdir("/Applications")] try: i = system_apps.index(app_name) return os.path.join("/Applications", system_apps[i]) except ValueError: try: i = system_apps.index(app_name + ".app") return os.path.join("/Applications", system_apps[i] + ".app") except ValueError: pass try: user_dir = os.path.expanduser("~/Applications/") user_apps = [f.lower() for f in os.listdir(user_dir)] try: i = user_apps.index(app_name) return os.path.join(user_dir, user_apps[i]) except ValueError: try: i = user_apps.index(app_name + ".app") return os.path.join("/Applications", user_apps[i] + ".app") except ValueError: pass except Exception: pass return None
def open_terminal(): """Try to figure which terminal is available.""" retcode = 1 if retcode and which("gnome-terminal") is not None: retcode = os.system("gnome-terminal -e 'ssh %s -X'" % cluster.hostname) if retcode and which("konsole") is not None: retcode = os.system("konsole -e 'ssh %s -X'" % cluster.hostname) # This does not work #retcode = os.system('open -a Terminal -n --args %s -X" % cluster.hostname") if retcode: # Fallback to xterm. retcode = os.system("xterm -e ssh %s -X" % cluster.hostname) return retcode
def abicheck(): """ This function tests if the most important ABINIT executables can be found in $PATH and whether the python modules needed at run-time can be imported. Raises: RuntimeError if not all the dependencies are fulfilled. """ import os # Executables must be in $PATH. Unfortunately we cannot # test the version of the binaries. # A possible approach would be to execute "exe -v" # but supporting argv in Fortran is not trivial. # Dynamic linking is tested by calling `ldd exe` executables = [ "abinit", "mrgddb", "mrggkk", "anaddb", ] has_ldd = which("ldd") is not None err_lines = [] app = err_lines.append for exe in executables: exe_path = which(exe) if exe_path is None: app("Cannot find %s in $PATH" % exe) else: if has_ldd and os.system("ldd %s > /dev/null " % exe_path) != 0: app("Missing shared library dependencies for %s" % exe) try: software_stack() except: app(_straceback()) if err_lines: header = "The environment on the local machine is not properly setup\n" raise RuntimeError(header + "\n".join(err_lines)) return 0
def __init__(self, *nc_args, **nc_kwargs): """ Args: nc_args: Arguments passed to ncdump. nc_kwargs: Keyword arguments passed to ncdump """ self.nc_args = nc_args self.nc_kwargs = nc_kwargs self.ncdump = which("ncdump")
def has_python_graphviz(need_dotexec=False): """ True if python-graphviz package is installed and dot executable in path. """ try: from graphviz import Digraph except ImportError: return False return which("dot") is not None if need_dotexec else True
def OnNetcdf_NcView(self, event): """Call ncview in an subprocess.""" if which("ncview") is None: return awx.showErrorMessage(self, "Cannot find ncview in $PATH") for path in self.nc_filepaths: def target(): os.system("ncview %s" % path) thread = awx.WorkerThread(self, target=target) thread.start()
def run(self): """ Perform the actual VASP run. Returns: (subprocess.Popen) Used for monitoring. """ cmd = list(self.vasp_cmd) if self.auto_gamma: vi = VaspInput.from_directory(".") kpts = vi["KPOINTS"] if kpts.style == "Gamma" and tuple(kpts.kpts[0]) == (1, 1, 1): if self.gamma_vasp_cmd is not None and which( self.gamma_vasp_cmd[-1]): cmd = self.gamma_vasp_cmd elif which(cmd[-1] + ".gamma"): cmd[-1] += ".gamma" logging.info("Running {}".format(" ".join(cmd))) with open(self.output_file, 'w') as f: p = subprocess.Popen(cmd, stdout=f) return p
class CODTest(unittest.TestCase): def setUp(self): warnings.simplefilter("ignore") def tearDown(self): warnings.resetwarnings() @unittest.skipIf(not which("mysql"), "No mysql.") def test_get_cod_ids(self): ids = COD().get_cod_ids("Li2O") self.assertTrue(len(ids) > 15) @unittest.skipIf(not which("mysql"), "No mysql.") def test_get_structure_by_formula(self): data = COD().get_structure_by_formula("Li2O") self.assertTrue(len(data) > 15) self.assertEqual(data[0]["structure"].composition.reduced_formula, "Li2O") def test_get_structure_by_id(self): s = COD().get_structure_by_id(2002926) self.assertEqual(s.formula, "Be8 H64 N16 F32")
def make_open_notebook(self, nbpath=None): """ Generate an ipython notebook open it in the browser. Return system exit code. Raise: RuntimeError if jupyther or ipython are not in $PATH """ path = self.write_notebook(nbpath=nbpath) cmd = "jupyter notebook %s" % path if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") return os.system(cmd)
def get_lmp_exe(): """ Get lammps executable Returns: Lammps executable name """ global LMP_EXE if LMP_EXE is not None: return LMP_EXE for lmp_exe in ["lmp_serial", "lmp_mpi"]: if which(lmp_exe) is not None: logger.info("Setting Lammps executable to %s" % lmp_exe) LMP_EXE = lmp_exe return lmp_exe
class LMPTest(unittest.TestCase): @unittest.skipIf(not which('lmp_serial'), 'No LAMMPS serial cmd found.') def test_get_lmp_exe(self): init_lmp = get_default_lmp_exe() lc = LatticeConstant(['dummy setting']) lc.set_lmp_exe(init_lmp) self.assertEqual(init_lmp, lc.LMP_EXE) new_lmp = "It can be any directory" lc.set_lmp_exe(new_lmp) self.assertEqual(new_lmp, lc.LMP_EXE) lc.set_lmp_exe(init_lmp)
def make_open_notebook(pseudopath, with_validation=False, with_eos=True): """ Generate an ipython notebook from the pseudopotential path and open it in the browser. Return system exit code. Raise: RuntimeError if jupyther or ipython are not in $PATH """ path = write_notebook(pseudopath, with_validation=with_validation, with_eos=with_eos, tmpfile=True) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") return os.system("jupyter notebook %s" % path)
def find_vasp_path(vasp_cmd="vasp_std", template="vaspjob.pbs", queue_type="pbs"): """ Find the location of vasp Parameter vasp_cmd: str The vasp command template: str (filename-like) The filename of the queue script. Default: vaspjob.pbs queue_type: str The type of queue system. Default: pbs Return vasp_path: (filename-like) str The dirname of vasp exe file, if not exists, return None """ vasp_path = None vasp_path = which(vasp_cmd) if not vasp_path: warnings.warn("DFTTK can't find vasp(by {}) in the environment, it will try to load it according to queue script. If you have loaded vasp, please specify correct vasp_cmd by -v or --vasp_cmd_flag".format(vasp_cmd)) if os.path.exists(template): param_dict = parse_queue_script(template=template, queue_type=queue_type, vasp_cmd_flag=vasp_cmd) if param_dict["pre_rocket"]: load_str = ";".join(param_dict["pre_rocket"]) + "; which " + vasp_cmd try: vasp_path_popen = subprocess.run(load_str, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) vasp_path = vasp_path_popen.stdout.decode('utf-8').strip() except Exception as e: raise ValueError("The load part in queue script({}) is incorrect.".format(template)) else: raise ValueError("In the queue script ({}), there is not load part. \ Please provide correct queue script for vasp or load vasp manual.".format(template)) else: warnings.warn("Queue script doesnot exists, it will try to load vasp automatically.") load_modules = ["vasp", "intel impi vasp"] for load_module in load_modules: load_str = "module load {}; which {}".format(load_module, vasp_cmd) try: vasp_path_popen = subprocess.run(load_str, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) vasp_path = vasp_path_popen.stdout.decode('utf-8').strip() break except Exception as e: pass if not vasp_path: raise EnvironmentError("DFTTK can't not load vasp automatically. Please provide the queue script or load vasp manual.") if vasp_path: vasp_path = os.path.dirname(vasp_path) print("SUCCESSFUL: vasp was found successful, and it is located at {}".format(vasp_path)) return vasp_path
class NudgedElasticBandTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.this_dir = os.path.dirname(os.path.abspath(__file__)) cls.test_dir = tempfile.mkdtemp() os.chdir(cls.test_dir) @classmethod def tearDownClass(cls): os.chdir(CWD) shutil.rmtree(cls.test_dir) def setUp(self): element_profile = {'Ni': {'r': 0.5, 'w': 1}} describer = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, pot_fit=True) model = LinearModel(describer=describer) model.model.coef_ = coeff model.model.intercept_ = intercept snap = SNAPotential(model=model) snap.specie = Element('Ni') self.struct = Structure.from_spacegroup('Fm-3m', Lattice.cubic(3.506), ['Ni'], [[0, 0, 0]]) self.ff_settings = snap @unittest.skipIf(not which('lmp_serial'), 'No LAMMPS serial cmd found.') @unittest.skipIf(not which('lmp_mpi'), 'No LAMMPS mpi cmd found.') def test_calculate(self): calculator = NudgedElasticBand(ff_settings=self.ff_settings, specie='Ni', lattice='fcc', alat=3.506) migration_barrier = calculator.calculate() np.testing.assert_almost_equal(migration_barrier, 1.013, decimal=2) invalid_calculator = NudgedElasticBand(ff_settings=self.ff_settings, specie='Ni', lattice='fccc', alat=3.506) self.assertRaises(ValueError, invalid_calculator.calculate)
def oncv_make_open_notebook(outpath): """ Generate an ipython notebook from the oncvpsp outputh and open it in the browser. Return system exit code. Raise: RuntimeError if jupyther or ipython are not in $PATH """ nbpath = oncv_write_notebook(outpath, nbpath=None) cmd = "jupyter notebook %s" % path if which("jupyter") is not None: return os.system("jupyter notebook %s" % nbpath) raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`")
def get_default_lmp_exe(): """ Get lammps executable Returns: Lammps executable name """ for lmp_exe in [ "lmp_serial", "lmp_mpi", "lmp_g++_serial", "lmp_g++_mpich", "lmp_intel_cpu_intelmpi" ]: if which(lmp_exe) is not None: logger.info("Setting Lammps executable to %s" % lmp_exe) return lmp_exe return None
def __init__(self, input_filename="lammps.in", bin="lammps"): """ Args: input_filename (string): input file name bin (string): command to run, excluding the input file name """ self.lammps_bin = bin.split() if not which(self.lammps_bin[-1]): raise RuntimeError( "LammpsRunner requires the executable {} to be in the path. " "Please download and install LAMMPS from " "http://lammps.sandia.gov. " "Don't forget to add the binary to your path".format(self.lammps_bin[-1])) self.input_filename = input_filename
class EnergyForceStressTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.this_dir = os.path.dirname(os.path.abspath(__file__)) cls.test_dir = tempfile.mkdtemp() os.chdir(cls.test_dir) @classmethod def tearDownClass(cls): os.chdir(CWD) shutil.rmtree(cls.test_dir) def setUp(self): element_profile = {'Ni': {'r': 0.5, 'w': 1}} describer1 = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, quadratic=False, pot_fit=True) model1 = LinearModel(describer=describer1) model1.model.coef_ = coeff model1.model.intercept_ = intercept snap1 = SNAPotential(model=model1) snap1.specie = Element('Ni') self.ff_settings1 = snap1 describer2 = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, quadratic=True, pot_fit=True) model2 = LinearModel(describer=describer2) model2.model.coef_ = coeff model2.model.intercept_ = intercept snap2 = SNAPotential(model=model2) snap2.specie = Element('Ni') self.ff_settings2 = snap2 self.struct = Structure.from_spacegroup('Fm-3m', Lattice.cubic(3.506), ['Ni'], [[0, 0, 0]]) @unittest.skipIf(not which('lmp_serial'), 'No LAMMPS cmd found.') def test_calculate(self): calculator1 = EnergyForceStress(ff_settings=self.ff_settings1) energy1, forces1, stresses1 = calculator1.calculate([self.struct])[0] self.assertTrue(abs(energy1 - (-23.1242962)) < 1e-2) np.testing.assert_array_almost_equal(forces1, np.zeros((len(self.struct), 3))) self.assertEqual(len(stresses1), 6)
def make_and_open_notebook(self, nbpath=None, foreground=False): # pragma: no cover """ Generate an jupyter_ notebook and open it in the browser. Args: nbpath: If nbpath is None, a temporay file is created. foreground: By default, jupyter is executed in background and stdout, stderr are redirected to devnull. Use foreground to run the process in foreground Return: system exit code. Raise: `RuntimeError` if jupyter_ is not in $PATH """ nbpath = self.write_notebook(nbpath=nbpath) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in $PATH. Install it with `conda install jupyter or `pip install jupyter`") # Use jupyter-lab instead of classic notebook if possible. has_jupyterlab = which("jupyter-lab") is not None #has_jupyterlab = False appname = "jupyter-lab" if has_jupyterlab else "jupyter notebook" if foreground: return os.system("%s %s" % (appname, nbpath)) else: fd, tmpname = tempfile.mkstemp(text=True) print(tmpname) cmd = "%s %s" % (appname, nbpath) print("Executing:", cmd) print("stdout and stderr redirected to %s" % tmpname) import subprocess process = subprocess.Popen(cmd.split(), shell=False, stdout=fd, stderr=fd) cprint("pid: %s" % str(process.pid), "yellow") return 0
def sendmail(subject, text, mailto, sender=None): """ Sends an e-mail either with unix sendmail. Args: subject: String with the subject of the mail. text: String with the body of the mail. mailto: String or list of string with the recipients. sender: string with the sender address. If sender is None, username@hostname is used. Returns: exit status """ def user_at_host(): from socket import gethostname return os.getlogin() + "@" + gethostname() # Body of the message. sender = user_at_host() if sender is None else sender if is_string(mailto): mailto = [mailto] from email.mime.text import MIMEText mail = MIMEText(text) mail["Subject"] = subject mail["From"] = sender mail["To"] = ", ".join(mailto) msg = mail.as_string() # sendmail works much better than the python interface. # Note that sendmail is available only on Unix-like OS. from subprocess import Popen, PIPE sendmail = which("sendmail") if sendmail is None: return -1 p = Popen([sendmail, "-t"], stdin=PIPE, stderr=PIPE) outdata, errdata = p.communicate(msg) return len(errdata)
def make_open_notebook(pseudopath, with_validation=False, with_eos=True, hide_code=False, tmpfile=True, foreground=False): """ Generate a jupyter notebook from the pseudopotential path and open it in the browser. Return system exit code. Args: pseudopath: Path to the pseudopotential file. with_validation: If True an ipython widget is added at the end of the notebook to validate the pseudopotential. with_eos: True if EOS plots are wanted. tmpfile: True if notebook should be written to temp location else build ipynb name from pseudo file. foreground: By default, jupyter is executed in background and stdout, stderr are redirected to devnull. Use foreground to run the process in foreground Raise: RuntimeError if jupyter is not in $PATH """ nbpath = write_notebook(pseudopath, with_validation=with_validation, with_eos=with_eos, tmpfile=tmpfile, hide_code=hide_code) if which("jupyter") is None: raise RuntimeError( "Cannot find jupyter in PATH. Install it with `pip install`") if foreground: cmd = "jupyter notebook %s" % nbpath return os.system(cmd) else: cmd = "jupyter notebook %s &> /dev/null &" % nbpath print("Executing:", cmd) import subprocess try: from subprocess import DEVNULL # py3k except ImportError: DEVNULL = open(os.devnull, "wb") process = subprocess.Popen(cmd.split(), shell=False, stdout=DEVNULL) #, stderr=DEVNULL) cprint("pid: %s" % str(process.pid), "yellow")
def sendmail(subject, text, mailto, sender=None): """ Sends an e-mail with unix sendmail. Args: subject: String with the subject of the mail. text: String with the body of the mail. mailto: String or list of string with the recipients. sender: string with the sender address. If sender is None, username@hostname is used. Returns: Exit status """ def user_at_host(): from socket import gethostname return os.getlogin() + "@" + gethostname() # Body of the message. try: sender = user_at_host() if sender is None else sender except OSError: sender = 'abipyscheduler@youknowwhere' if is_string(mailto): mailto = [mailto] from email.mime.text import MIMEText mail = MIMEText(text) mail["Subject"] = subject mail["From"] = sender mail["To"] = ", ".join(mailto) msg = mail.as_string() # sendmail works much better than the python interface. # Note that sendmail is available only on Unix-like OS. from subprocess import Popen, PIPE import sys sendmail = which("sendmail") if sendmail is None: return -1 if sys.version_info[0] < 3: p = Popen([sendmail, "-t"], stdin=PIPE, stderr=PIPE) else: # msg is string not bytes so must use universal_newlines p = Popen([sendmail, "-t"], stdin=PIPE, stderr=PIPE, universal_newlines=True) outdata, errdata = p.communicate(msg) return len(errdata)
def run(self): """ Perform the actual VASP run. Returns: (subprocess.Popen) Used for monitoring. """ cmd = list(self.vasp_cmd) if self.auto_gamma: kpts = Kpoints.from_file("KPOINTS") if kpts.style == Kpoints.supported_modes.Gamma \ and tuple(kpts.kpts[0]) == (1, 1, 1): if self.gamma_vasp_cmd is not None and which( self.gamma_vasp_cmd[-1]): cmd = self.gamma_vasp_cmd elif which(cmd[-1] + ".gamma"): cmd[-1] += ".gamma" logger.info("Running {}".format(" ".join(cmd))) with open(self.output_file, 'w') as f_std, \ open(self.stderr_file, "w", buffering=1) as f_err: # Use line buffering for stderr p = subprocess.Popen(cmd, stdout=f_std, stderr=f_err) return p
def make_open_notebook(self, nbpath=None): """ Generate an ipython notebook and open it in the browser. If nbpath is None, a temporay file is created. Return system exit code. Raise: RuntimeError if jupyther or ipython are not in $PATH """ nbpath = self.write_notebook(nbpath=nbpath) from monty.os.path import which if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") return os.system("jupyter notebook %s" % nbpath)
def __init__(self, mols, param_list, input_file="pack.inp", tolerance=2.0, filetype="xyz", control_params={"maxit": 20, "nloop": 600}, auto_box=True, output_file="packed.xyz", bin="packmol"): """ Args: mols: list of Molecules to pack input_file: name of the packmol input file tolerance: min distance between the atoms filetype: input/output structure file type control_params: packmol control parameters dictionary. Basically all parameters other than structure/atoms param_list: list of parameters containing dicts for each molecule auto_box: put the molecule assembly in a box output_file: output file name. The extension will be adjusted according to the filetype """ self.packmol_bin = bin.split() if not which(self.packmol_bin[-1]): raise RuntimeError( "PackmolRunner requires the executable 'packmol' to be in " "the path. Please download packmol from " "https://github.com/leandromartinez98/packmol " "and follow the instructions in the README to compile. " "Don't forget to add the packmol binary to your path") self.mols = mols self.param_list = param_list self.input_file = input_file self.boxit = auto_box self.control_params = control_params if not self.control_params.get("tolerance"): self.control_params["tolerance"] = tolerance if not self.control_params.get("filetype"): self.control_params["filetype"] = filetype if not self.control_params.get("output"): self.control_params["output"] = "{}.{}".format( output_file.split(".")[0], self.control_params["filetype"]) if self.boxit: self._set_box()
def make_and_open_notebook(options): """ Generate an jupyter notebook and open it in the browser. Return system exit code. Raise: RuntimeError if jupyther is not in $PATH """ import os import nbformat nbf = nbformat.v4 nb = nbf.new_notebook() nb.cells.extend([ nbf.new_markdown_cell("## This is an auto-generated notebook for %s" % os.path.relpath(options.filepath)), nbf.new_code_cell("""\ from __future__ import print_function, division, unicode_literals, absolute_import %matplotlib notebook import numpy as np #import seaborn as sns #sns.set(context='notebook', style='darkgrid', palette='deep', # font='sans-serif', font_scale=1, color_codes=False, rc=None) from abipy import abilab\ """), nbf.new_code_cell("abifile = abilab.abiopen('%s')" % options.filepath) ]) import io, tempfile _, nbpath = tempfile.mkstemp(prefix="abinb_", suffix='.ipynb', dir=os.getcwd(), text=True) with io.open(nbpath, 'wt', encoding="utf8") as f: nbformat.write(nb, f) if which("jupyter") is None: raise RuntimeError("Cannot find jupyter in PATH. Install it with `pip install`") if options.foreground: return os.system("jupyter notebook %s" % nbpath) else: fd, tmpname = tempfile.mkstemp(text=True) print(tmpname) cmd = "jupyter notebook %s" % nbpath print("Executing:", cmd) print("stdout and stderr redirected to %s" % tmpname) import subprocess process = subprocess.Popen(cmd.split(), shell=False, stdout=fd, stderr=fd) cprint("pid: %s" % str(process.pid), "yellow")
def __init__(self, input_filename="lammps.in", bin="lammps"): """ LAMMPS wrapper Args: input_filename (string): input file name bin (string): command to run, excluding the input file name """ self.lammps_bin = bin.split() if not which(self.lammps_bin[-1]): raise RuntimeError( "LammpsRunner requires the executable {} to be in the path. " "Please download and install LAMMPS from " \ "http://lammps.sandia.gov. " "Don't forget to add the binary to your path".format(self.lammps_bin[-1])) self.input_filename = input_filename
def run(self, path: Union[str, Path], timeout=30): """Run packmol and write out the packed structure. Args: path: The path in which packmol input files are located. timeout: Timeout in seconds. Raises: ValueError if packmol does not succeed in packing the box. TimeoutExpiredError if packmold does not finish within the timeout. """ wd = os.getcwd() if not which("packmol"): raise RuntimeError( "Running a PackmolSet requires the executable 'packmol' to be in " "the path. Please download packmol from " "https://github.com/leandromartinez98/packmol " "and follow the instructions in the README to compile. " "Don't forget to add the packmol binary to your path") try: os.chdir(path) p = subprocess.run( f"packmol < '{self.inputfile}'", check=True, shell=True, timeout=timeout, capture_output=True, ) # this workaround is needed because packmol can fail to find # a solution but still return a zero exit code # see https://github.com/m3g/packmol/issues/28 if "ERROR" in p.stdout.decode(): if "Could not open file." in p.stdout.decode(): raise ValueError( "Your packmol might be too old to handle paths with spaces." "Please try again with a newer version or use paths without spaces." ) msg = p.stdout.decode().split("ERROR")[-1] raise ValueError( f"Packmol failed with return code 0 and stdout: {msg}") except subprocess.CalledProcessError as e: raise ValueError( f"Packmol failed with errorcode {e.returncode} and stderr: {e.stderr}" ) from e else: with open(Path(path, self.stdoutfile), "w") as out: out.write(p.stdout.decode()) finally: os.chdir(wd)
def __init__(self, **kwargs): """ Initializer for lammps calculator Allowed keyword args are lmp_exe string """ lmp_exe = kwargs.pop("lmp_exe", None) if lmp_exe is None: lmp_exe = get_default_lmp_exe() if not which(lmp_exe): raise ValueError("lammps executable %s not found" % str(lmp_exe)) self.LMP_EXE = lmp_exe for i, j in kwargs.items(): if i not in self.allowed_kwargs: raise TypeError("%s not in supported kwargs %s" % (str(i), str(self.allowed_kwargs))) setattr(self, i, j)
def __init__(self, executable=None, verbose=0): """ Args: executable: path to the executable. verbose: Verbosity level. """ if executable is None: executable = self.name self.executable = which(executable) self.verbose = int(verbose) if self.executable is None: raise self.Error("Cannot find %s in $PATH\n Use export PATH=/dir_with_exec:$PATH" % executable) assert os.path.basename(self.executable) == self.name
def make_and_open_notebook(options): """ Generate an ipython notebook and open it in the browser. Return system exit code. Raise: RuntimeError if jupyther is not in $PATH """ import os import nbformat nbf = nbformat.v4 nb = nbf.new_notebook() nb.cells.extend([ nbf.new_markdown_cell("## This is an auto-generated notebook for %s" % os.path.relpath(options.filepath)), nbf.new_code_cell("""\ from __future__ import print_function, division, unicode_literals, absolute_import %matplotlib notebook import numpy as np #import seaborn as sns from abipy import abilab\ """), nbf.new_code_cell("abifile = abilab.abiopen('%s')" % options.filepath) ]) import io, tempfile _, nbpath = tempfile.mkstemp(prefix="abinb_", suffix='.ipynb', dir=os.getcwd(), text=True) with io.open(nbpath, 'wt', encoding="utf8") as f: nbformat.write(nb, f) if which("jupyter") is None: raise RuntimeError( "Cannot find jupyter in PATH. Install it with `pip install`") cmd = "jupyter notebook %s" % nbpath if options.no_daemon: return os.system(cmd) else: import daemon with daemon.DaemonContext(): return os.system(cmd)
def setUpClass(cls): print("Testing with: ", which("vampire-serial")) cls.Mn3Al = pd.read_json(os.path.join(test_dir, "Mn3Al.json")) cls.compounds = [cls.Mn3Al] cls.structure_inputs = [] cls.energy_inputs = [] for c in cls.compounds: ordered_structures = list(c["structure"]) ordered_structures = [Structure.from_dict(d) for d in ordered_structures] epa = list(c["energy_per_atom"]) energies = [e * len(s) for (e, s) in zip(epa, ordered_structures)] cls.structure_inputs.append(ordered_structures) cls.energy_inputs.append(energies)
def run(self): """Run Abinit and rename output files. Return 0 if success""" from monty.os.path import which if which(self.executable) is None: raise RuntimeError("Cannot find %s in $PATH" % self.executable) os.chdir(self.workdir) process = self._run() process.wait() if process.returncode != 0: print("returncode == %s" % process.returncode) print(process.stderr.readlines()) return process.returncode if self.finalize: self._finalize() return 0
def __init__(self, executable=None, verbose=0): """ Args: executable: path to the executable. verbose: Verbosity level. """ if executable is None: executable = self.name self.executable = which(executable) self.verbose = int(verbose) if self.executable is None: raise self.Error( "Cannot find %s in $PATH\n Use export PATH=/dir_with_exec:$PATH" % executable) assert os.path.basename(self.executable) == self.name
class BispectrumCoefficientsTest(unittest.TestCase): @unittest.skipIf(not which("lmp_serial"), "No LAMMPS cmd found") def test_transform(self): s = Structure.from_spacegroup('Fm-3m', Lattice.cubic(5.69169), ['Na', 'Cl'], [[0, 0, 0], [0, 0, 0.5]]) profile = dict(Na=dict(r=0.3, w=0.9), Cl=dict(r=0.7, w=3.0)) s *= [2, 2, 2] structures = [s] * 10 for s in structures: n = np.random.randint(4) inds = np.random.randint(16, size=n) s.remove_sites(inds) bc_atom = BispectrumCoefficients(cutoff=5, twojmax=3, element_profile=profile, quadratic=False, pot_fit=False) df_atom = bc_atom.transform(structures) for i, s in enumerate(structures): df_s = df_atom.xs(i, level='input_index') self.assertEqual(df_s.shape, (len(s), 8)) self.assertTrue(df_s.equals(bc_atom.transform_one(s))) bc_pot = BispectrumCoefficients(cutoff=5, twojmax=3, element_profile=profile, quadratic=False, pot_fit=True, include_stress=True) df_pot = bc_pot.transform(structures) for i, s in enumerate(structures): df_s = df_pot.xs(i, level='input_index') self.assertEqual(df_s.shape, (1 + len(s) * 3 + 6, 18)) self.assertTrue(df_s.equals(bc_pot.transform_one(s))) sna = df_s.iloc[0] for specie in ['Na', 'Cl']: self.assertAlmostEqual( sna[specie, 'n'], s.composition.fractional_composition[specie]) np.testing.assert_array_equal(df_s[specie, 'n'][1:], np.zeros(len(s) * 3 + 6))
def __init__(self, **kwargs): """ Args: workdir: Working directory. finalize: True if self.finalize is called verbose: Verbosity level. """ if not hasattr(self, "files_to_save"): raise ValueError("files_to_save are not defined") from monty.os.path import which if which(self.executable) is None: raise RuntimeError("Cannot find %s in $PATH" % self.executable) self.workdir = os.path.abspath(kwargs.pop("workdir", ".")) self.finalize = kwargs.pop("finalize", True) self.verbose = kwargs.pop("verbose", 1) self.files_to_keep = set([os.path.basename(__file__), "run.abi", "run.abo"] + list(self.files_to_save.keys()))
class DefectFormationTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.this_dir = os.path.dirname(os.path.abspath(__file__)) cls.test_dir = tempfile.mkdtemp() os.chdir(cls.test_dir) @classmethod def tearDownClass(cls): os.chdir(CWD) shutil.rmtree(cls.test_dir) def setUp(self): element_profile = {"Ni": {"r": 0.5, "w": 1}} describer = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, pot_fit=True) model = SKLModel(describer=describer, model=LinearRegression()) model.model.coef_ = coeff model.model.intercept_ = intercept snap = SNAPotential(model=model) self.struct = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.506), ["Ni"], [[0, 0, 0]]) self.ff_settings = snap @unittest.skipIf(not which("lmp_serial"), "No LAMMPS serial cmd found.") def test_calculate(self): calculator = DefectFormation(ff_settings=self.ff_settings, specie="Ni", lattice="fcc", alat=3.506) defect_formation_energy = calculator.calculate() np.testing.assert_almost_equal(defect_formation_energy, 1.502, decimal=2) invalid_calculator = DefectFormation(ff_settings=self.ff_settings, specie="Ni", lattice="fccc", alat=3.506) self.assertRaises(ValueError, invalid_calculator.calculate)
def make_and_open_notebook(self, nbpath=None, foreground=False): """ Generate an ipython notebook and open it in the browser. Args: nbpath: If nbpath is None, a temporay file is created. foreground: By default, jupyter is executed in background and stdout, stderr are redirected to devnull. Use foreground to run the process in foreground Return: system exit code. Raise: RuntimeError if jupyter is not in $PATH """ nbpath = self.write_notebook(nbpath=nbpath) if which("jupyter") is None: raise RuntimeError( "Cannot find jupyter in PATH. Install it with `conda install jupyter or `pip install jupyter`" ) if foreground: cmd = "jupyter notebook %s" % nbpath return os.system(cmd) else: cmd = "jupyter notebook %s &> /dev/null &" % nbpath print("Executing:", cmd) import subprocess cmd = "jupyter notebook %s" % nbpath try: from subprocess import DEVNULL # py3k except ImportError: DEVNULL = open(os.devnull, "wb") process = subprocess.Popen(cmd.split(), shell=False, stdout=DEVNULL, stderr=DEVNULL) cprint("pid: %s" % str(process.pid), "yellow")
def write_notebook_html(pseudopath, with_validation=False, with_eos=True, hide_code=True, tmpfile=True, mock=False): """ Generate a jupyter notebook from the pseudopotential path and write the static html version of the executed notebook. Return system exit code. Args: with_validation: If True an ipython widget is added at the end of the notebook to validate the pseudopotential. with_eos: True if EOS plots are wanted. hide_code: True to hide python code in notebook. tmpfile: True if notebook should be written to temp location else build ipynb name from pseudo file. mock: for testing purposes, creating actual html takes much time Raise: RuntimeError if nbconvert is not in $PATH """ if mock: html_path = pseudopath.split('.')[0] + '.html' with open(html_path, 'w') as f: f.write('mock file') return path = write_notebook(pseudopath, with_validation=with_validation, with_eos=with_eos, tmpfile=tmpfile, hide_code=hide_code, inline=True) if which("jupyter") is None: raise RuntimeError( "Cannot find jupyter in PATH. This is needed to save the static HTML version of " "a notebook. Install it with `pip install`") return os.system("jupyter nbconvert --to html --execute %s" % path)
class LatticeConstantTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.this_dir = os.path.dirname(os.path.abspath(__file__)) cls.test_dir = tempfile.mkdtemp() os.chdir(cls.test_dir) @classmethod def tearDownClass(cls): os.chdir(CWD) shutil.rmtree(cls.test_dir) def setUp(self): element_profile = {'Ni': {'r': 0.5, 'w': 1}} describer = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, pot_fit=True) model = LinearModel(describer=describer) model.model.coef_ = coeff model.model.intercept_ = intercept snap = SNAPotential(model=model) snap.specie = Element('Ni') self.struct = Structure.from_spacegroup('Fm-3m', Lattice.cubic(3.506), ['Ni'], [[0, 0, 0]]) self.ff_settings = snap @unittest.skipIf(not which('lmp_serial'), 'No LAMMPS cmd found.') def test_calculate(self): calculator = LatticeConstant(ff_settings=self.ff_settings) a, b, c = self.struct.lattice.abc calc_a, calc_b, calc_c = calculator.calculate([self.struct])[0] np.testing.assert_almost_equal(calc_a, a, decimal=2) np.testing.assert_almost_equal(calc_b, b, decimal=2) np.testing.assert_almost_equal(calc_c, c, decimal=2)
def find_loc(app_name): """Returns the location of the application from its name.""" # Try command line version path = which(app_name) if path is not None: return path # Treat Mac OsX applications. if is_macosx(): system_apps = [f.lower() for f in os.listdir("/Applications")] try: i = system_apps.index(app_name) return os.path.join("/Applications", system_apps[i]) except ValueError: try: i = system_apps.index(app_name + ".app") return os.path.join("/Applications", system_apps[i] + ".app") except ValueError: pass try: user_dir = os.path.expanduser("~/Applications/") user_apps = [f.lower() for f in os.listdir(user_dir)] try: i = user_apps.index(app_name) return os.path.join(user_dir, user_apps[i]) except ValueError: try: i = user_apps.index(app_name + ".app") return os.path.join("/Applications", user_apps[i] + ".app") except ValueError: pass except: pass return None
def draw_graph_to_file(self, filename="graph", diff=None, hide_unconnected_nodes=False, hide_image_edges=True, edge_colors=False, node_labels=False, weight_labels=False, image_labels=False, color_scheme="VESTA", keep_dot=False, algo="fdp"): """ Draws graph using GraphViz. The networkx graph object itself can also be drawn with networkx's in-built graph drawing methods, but note that this might give misleading results for multigraphs (edges are super-imposed on each other). If visualization is difficult to interpret, `hide_image_edges` can help, especially in larger graphs. :param filename: filename to output, will detect filetype from extension (any graphviz filetype supported, such as pdf or png) :param diff (StructureGraph): an additional graph to compare with, will color edges red that do not exist in diff and edges green that are in diff graph but not in the reference graph :param hide_unconnected_nodes: if True, hide unconnected nodes :param hide_image_edges: if True, do not draw edges that go through periodic boundaries :param edge_colors (bool): if True, use node colors to color edges :param node_labels (bool): if True, label nodes with species and site index :param weight_labels (bool): if True, label edges with weights :param image_labels (bool): if True, label edges with their periodic images (usually only used for debugging, edges to periodic images always appear as dashed lines) :param color_scheme (str): "VESTA" or "JMOL" :param keep_dot (bool): keep GraphViz .dot file for later visualization :param algo: any graphviz algo, "neato" (for simple graphs) or "fdp" (for more crowded graphs) usually give good outputs :return: """ if not which(algo): raise RuntimeError("StructureGraph graph drawing requires " "GraphViz binaries to be in the path.") # Developer note: NetworkX also has methods for drawing # graphs using matplotlib, these also work here. However, # a dedicated tool like GraphViz allows for much easier # control over graph appearance and also correctly displays # mutli-graphs (matplotlib can superimpose multiple edges). g = self.graph.copy() g.graph = {'nodesep': 10.0, 'dpi': 300, 'overlap': "false"} # add display options for nodes for n in g.nodes(): # get label by species name label = "{}({})".format(str(self.structure[n].specie), n) if node_labels else "" # use standard color scheme for nodes c = EL_COLORS[color_scheme].get(str(self.structure[n].specie.symbol), [0, 0, 0]) # get contrasting font color # magic numbers account for perceived luminescence # https://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color fontcolor = '#000000' if 1 - (c[0] * 0.299 + c[1] * 0.587 + c[2] * 0.114) / 255 < 0.5 else '#ffffff' # convert color to hex string color = "#{:02x}{:02x}{:02x}".format(c[0], c[1], c[2]) g.add_node(n, fillcolor=color, fontcolor=fontcolor, label=label, fontname="Helvetica-bold", style="filled", shape="circle") edges_to_delete = [] # add display options for edges for u, v, k, d in g.edges(keys=True, data=True): # retrieve from/to images, set as origin if not defined to_image = d['to_jimage'] # set edge style d['style'] = "solid" if to_image != (0, 0, 0): d['style'] = "dashed" if hide_image_edges: edges_to_delete.append((u, v, k)) # don't show edge directions d['arrowhead'] = "none" # only add labels for images that are not the origin if image_labels: d['headlabel'] = "" if to_image == (0, 0, 0) else "to {}".format((to_image)) d['arrowhead'] = "normal" if d['headlabel'] else "none" # optionally color edges using node colors color_u = g.node[u]['fillcolor'] color_v = g.node[v]['fillcolor'] d['color_uv'] = "{};0.5:{};0.5".format(color_u, color_v) if edge_colors else "#000000" # optionally add weights to graph if weight_labels: units = g.graph.get('edge_weight_units', "") if d.get('weight'): d['label'] = "{:.2f} {}".format(d['weight'], units) # update edge with our new style attributes g.edges[u, v, k].update(d) # optionally remove periodic image edges, # these can be confusing due to periodic boundaries if hide_image_edges: for edge_to_delete in edges_to_delete: g.remove_edge(*edge_to_delete) # optionally hide unconnected nodes, # these can appear when removing periodic edges if hide_unconnected_nodes: g = g.subgraph([n for n in g.degree() if g.degree()[n] != 0]) # optionally highlight differences with another graph if diff: diff = self.diff(diff, strict=True) green_edges = [] red_edges = [] for u, v, k, d in g.edges(keys=True, data=True): if (u, v, d['to_jimage']) in diff['self']: # edge has been deleted red_edges.append((u, v, k)) elif (u, v, d['to_jimage']) in diff['other']: # edge has been added green_edges.append((u, v, k)) for u, v, k in green_edges: g.edges[u, v, k].update({'color_uv': '#00ff00'}) for u, v, k in red_edges: g.edges[u, v, k].update({'color_uv': '#ff0000'}) basename, extension = os.path.splitext(filename) extension = extension[1:] write_dot(g, basename+".dot") with open(filename, "w") as f: args = [algo, "-T", extension, basename+".dot"] rs = subprocess.Popen(args, stdout=f, stdin=subprocess.PIPE, close_fds=True) rs.communicate() if rs.returncode != 0: raise RuntimeError("{} exited with return code {}.".format(algo, rs.returncode)) if not keep_dot: os.remove(basename+".dot")
import os import unittest import warnings from monty.os.path import which from pymatgen.core.periodic_table import Element from pymatgen.core.structure import Structure from pymatgen.command_line.enumlib_caller import EnumError, EnumlibAdaptor from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.transformations.site_transformations import RemoveSitesTransformation from pymatgen.transformations.standard_transformations import SubstitutionTransformation from pymatgen.util.testing import PymatgenTest enum_cmd = which("enum.x") or which("multienum.x") makestr_cmd = which("makestr.x") or which("makeStr.x") or which("makeStr.py") enumlib_present = enum_cmd and makestr_cmd @unittest.skipIf(not enumlib_present, "enum_lib not present.") class EnumlibAdaptorTest(PymatgenTest): _multiprocess_shared_ = True def test_init(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") struct = self.get_structure("LiFePO4") subtrans = SubstitutionTransformation({"Li": {"Li": 0.5}}) adaptor = EnumlibAdaptor(subtrans.apply_transformation(struct), 1, 2) adaptor.run()
def get_table(): """ Loads a lightweight lambda table for use in unit tests to reduce initialization time, and make unit tests insensitive to changes in the default lambda table. """ data_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", 'test_files', 'struct_predictor') json_file = os.path.join(data_dir, 'test_lambda.json') with open(json_file) as f: lambda_table = json.load(f) return lambda_table enum_cmd = which('enum.x') or which('multienum.x') makestr_cmd = which('makestr.x') or which('makeStr.x') or which('makeStr.py') mcsqs_cmd = which('mcsqs') enumlib_present = enum_cmd and makestr_cmd class SuperTransformationTest(unittest.TestCase): def setUp(self): warnings.simplefilter("ignore") def tearDown(self): warnings.simplefilter("default") def test_apply_transformation(self): tl = [SubstitutionTransformation({"Li+": "Na+"}),