def functional(indiv, outdir=None, value=False, **kwargs): from pylada.misc import local_path from pickle import dump outdir = local_path(outdir) outdir.ensure(dir=True) dump((indiv, value), outdir.join('OUTCAR').open('wb')) return Extract(str(outdir))
def completer(self, event): """ Completer for %record magic function. """ from pylada.misc import local_path from pickle import load from os.path import isdir, exists result = [] data = event.line.split()[1:] if (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--n") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--n") \ or (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--namespace") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--namespace"): return [key for key, value in self.api.user_ns.items() if key[0] != '_' and hasattr(value, '__dict__')] if (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--file") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--file"): other = event.symbol string = '%mglob "cont:This is a record." {0}*'.format(other) result = [u for u in self.api.magic(string)] string = '%mglob dir:{0}*'.format(other) result.extend([u for u in self.api.magic(string)]) if isdir(other) and other[-1] != '/': string = '%mglob "cont:This is a record." {0}/*'.format(other) result.extend([u for u in self.api.magic(string)]) return result if '--file' not in data: result.append('--file') options = {'--list', '--view', '--load', '--remove', '--update'} if '-n' in data or '--namespace' in data and '--load' not in data: result.append('--load') elif '--load' in data and '-n' not in data and '--namespace' not in data: result.append('--namespace') elif len(options.intersection(set(data))) == 0: result.extend(['--list', '--view', '--load', '--remove', '--namespace', '--update']) if len(set(['--load', '--remove', '--view']).intersection(set(data))) != 0: path = '.pylada_record' known = [u for u in data] if '--file' in data: index = data.index('--file') assert len(data) > index + 1 path = str(local_path(data[index + 1])) known.pop(index + 1) if exists(path): with open(path) as file: keys = load(file) if '--namespace' in known: index = known.index('--namespace') if len(known) > index + 1: known.pop(index + 1) if '-n' in known: index = known.index('-n') if len(known) > index + 1: known.pop(index + 1) result.extend(keys - set(known)) else: result.extend([u for u in self.api.user_ns.keys() if u[0] != '_']) return result
def call_functional(indiv, outdir=None, value=False, **kwargs): from pylada.misc import local_path from pickle import dump path = local_path(outdir) path.ensure(dir=True) dump((indiv, value), path.join("OUTCAR").open("wb")) return Extract(outdir)
def run_with_restart(outdir="restarting"): """ Example of running relaxation with cell-shape """ from pylada.misc import local_path from numpy.random import random outdir = local_path(outdir) structure = diamond_structure() pwscf = diamond_pwscf() structure[1].pos += random(3) * 0.01 - 0.005 structure.cell += random((3, 3)) * 0.01 - 0.005 pwscf.control.calculation = 'vc-relax' pwscf.cell.factor = 2.0 result = pwscf(structure, outdir=outdir.join('first')) result = pwscf(structure, outdir=outdir.join('second'), restart=result)
def functional(structure, outdir=None, value=False, **kwargs): """ A dummy functional """ from copy import deepcopy from pickle import dump from random import random from pylada.misc import local_path structure = deepcopy(structure) structure.value = value outdir = local_path(outdir) outdir.ensure(dir=True) dump((random(), structure, value, functional), outdir.join('OUTCAR').open('wb')) return Extract(outdir) return structure
def Extract(outdir=None): """ An extraction function for a dummy functional """ from os import getcwd from collections import namedtuple from pickle import load from pylada.misc import local_path if outdir == None: outdir = getcwd() Extract = namedtuple('Extract', ['success', 'directory', 'energy', 'structure', 'value', 'functional']) outdir = local_path(outdir) if not outdir.check(): return Extract(False, str(outdir), None, None, None, None) if not outdir.join('OUTCAR').check(file=True): return Extract(False, str(outdir), None, None, None, None) with local_path.join('OUTCAR').open('r') as file: structure, energy, value, functional = load(file) return Extract(True, outdir, energy, structure, value, functional)
def Extract(outdir=None): from os.path import exists from os import getcwd from collections import namedtuple from pickle import load from pylada.misc import local_path if outdir == None: outdir = getcwd() Extract = namedtuple('Extract', ['success', 'directory', 'indiv', 'functional']) if not exists(outdir): return Extract(False, outdir, None, functional) outdir = local_path(outdir) if not outdir.join('OUTCAR').check(file=True): return Extract(False, str(outdir), None, functional) indiv, value = load(outdir.join('OUTCAR').open('rb')) return Extract(True, outdir, indiv, functional)
def Extract(outdir=None): from os.path import exists from os import getcwd from collections import namedtuple from pickle import load from pylada.misc import local_path if outdir == None: outdir = getcwd() Extract = namedtuple("Extract", ["success", "directory", "indiv", "functional"]) if not exists(outdir): return Extract(False, outdir, None, functional) outdir = local_path(outdir) if not outdir.join("OUTCAR").check(file=True): return Extract(False, str(outdir), None, functional) indiv, value = load(outdir.join("OUTCAR").open("rb")) return Extract(True, outdir, indiv, functional_call)
def __init__(self, directory): from pylada.misc import local_path self.directory = str(local_path(directory))
def test_icharg(): from time import sleep from collections import namedtuple from pickle import loads, dumps from os import remove, makedirs from os.path import join, exists from shutil import rmtree from tempfile import mkdtemp from pylada.vasp.files import WAVECAR, CHGCAR from pylada.vasp import Vasp from pylada.misc import local_path from pylada.error import ValueError Extract = namedtuple("Extract", ['directory', 'success']) a = Vasp() o = a._input['icharg'] d = {'ICharg': o.__class__} directory = mkdtemp() if directory in ['/tmp/test', '/tmp/test/']: if exists(directory): rmtree(directory) makedirs(directory) try: assert a.icharg == 'auto' assert o.output_map(vasp=a, outdir=directory)['icharg'] == '2' assert eval(repr(o), d).value == 'auto' assert loads(dumps(o)).value == 'auto' restartdir = join(directory, 'restart') local_path(restartdir).ensure(dir=True) with open(join(restartdir, CHGCAR), 'w') as file: file.write('hello') with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') # do not copy if not successful a.restart = Extract(restartdir, False) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '2' assert not exists(join(directory, CHGCAR)) assert not exists(join(directory, WAVECAR)) # do not copy if empty with open(join(restartdir, CHGCAR), 'w') as file: pass with open(join(restartdir, WAVECAR), 'w') as file: pass a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '2' assert not exists(join(directory, CHGCAR)) assert not exists(join(directory, WAVECAR)) # now copy only CHGCAR with open(join(restartdir, CHGCAR), 'w') as file: file.write('hello') a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '1' assert exists(join(directory, CHGCAR)) assert not exists(join(directory, WAVECAR)) remove(join(directory, CHGCAR)) # now copy only CHGCAR with scf a.nonscf = True a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '11' assert exists(join(directory, CHGCAR)) assert not exists(join(directory, WAVECAR)) remove(join(directory, CHGCAR)) # now copy both a.nonscf = False with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '0' assert exists(join(directory, CHGCAR)) assert exists(join(directory, WAVECAR)) # now copy both with scf a.nonscf = True a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '10' assert exists(join(directory, CHGCAR)) assert exists(join(directory, WAVECAR)) # now check that latest is copied remove(join(restartdir, CHGCAR)) remove(join(directory, CHGCAR)) sleep(1.2) with open(join(directory, WAVECAR), 'w') as file: file.write('hello world') with open(join(directory, WAVECAR), 'r') as file: pass # Buffering issues.. a.nonscf = False a.restart = Extract(restartdir, True) assert o.output_map(vasp=a, outdir=directory)['icharg'] == '0' assert exists(join(directory, WAVECAR)) with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() == 'hello world' with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() != 'hello' with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') assert o.output_map(vasp=a, outdir=directory)['icharg'] == '0' assert exists(join(directory, WAVECAR)) with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() == 'hello' with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() != 'hello world' # makes sure requests are honored # tries request. Should fail since CHGCAR does not exist. remove(join(directory, WAVECAR)) a.icharg = 'chgcar' assert a.icharg == 'chgcar' try: o.output_map(vasp=a, outdir=directory) except ValueError: pass else: raise Exception() # now try for gold. with open(join(restartdir, CHGCAR), 'w') as file: file.write('hello') assert o.output_map(vasp=a, outdir=directory)['icharg'] == '1' assert exists(join(directory, CHGCAR)) assert not exists(join(directory, WAVECAR)) assert eval(repr(o), d).value == 'chgcar' assert loads(dumps(o)).value == 'chgcar' finally: if directory not in ['/tmp/test', '/tmp/test/'] and exists(directory): rmtree(directory)
def launch_program(cmdl, comm=None, formatter=None, env=None, stdout=None, stderr=None, stdin=None, outdir=None): """ Command used to launch a program. This function launches external programs for Pylada. It is included as a global so that it can be adapted to different computing environment. It also makes it easier to debug Pylada's mpi configuration when installing on a new machine. .. note:: The number one configuration problem is an incorrect :py:data:`~pylada.mpirun_exe`. .. note:: The number two configuration problem is mpi-placement (eg how to launch two different mpi program simultaneously in one PBS/SLURM job). First read the manual for the mpi environment on the particular machine Pylada is installed on. Then adapt :py:function:`~pylada.machine_dependent_call_modifier` by redeclaring it in $HOME/.pylada. :param str cmld: Command-line string. It will be formatted using ``formatter`` or ``comm`` if either are present. Otherwise, it should be exactly the (bash) command-prompt. :param comm: Should contain everythin needed to launch an mpi call. In practice, it is copied from :py:data:`~pylada.default_comm` and modified for the purpose of a particular call (e.g. could use fewer than all available procs) :type comm: :py:class:`~pylada.process.mpi.Communicator` :param dict formatter: Dictionary with which to format the communicator. If ``comm`` is present, then it will be updated with ``comm``'s input. :param dict env: Dictionary containing the environment variables in which to do call. :param stdout: File object to which to hook-up the standard output. See Popen_. :param stderr: File object to which to hook-up the standard error. See Popen_. :param str outdir: Path to the working directory. .. _Popen:: http://docs.python.org/library/subprocess.html#popen-constructor """ from shlex import split as shlex_split from subprocess import Popen from pylada import machine_dependent_call_modifier from pylada.misc import local_path # At this point formatter is {"program": vasp} # and cmdl is "mpirun -n {n} {placement} {program}" # Set in formatter: 'placement': '', 'ppn': 8, 'n': 8 # make sure that the formatter contains stuff from the communicator, eg the # number of processes. if comm is not None and formatter is not None: formatter.update(comm) # Set in formatter: 'placement': '-machinefile /home.../pylada_commtempfile' # Stuff that will depend on the supercomputer. machine_dependent_call_modifier(formatter, comm, env) # if a formatter exists, then use it on the cmdl string. if formatter is not None: cmdl = cmdl.format(**formatter) # otherwise, if comm is not None, use that. elif comm is not None: cmdl = cmdl.format(**comm) # Split command from string to list cmdl = shlex_split(cmdl) # makes sure the directory exists: local_path(outdir).ensure(dir=True) # Finally, start the process. popen = Popen(cmdl, stdout=stdout, stderr=stderr, stdin=stdin, cwd=outdir, env=env) popen.wait() #if testValidProgram: popen.wait() return popen
def test_istart(): from time import sleep from collections import namedtuple from pickle import loads, dumps from os import remove, makedirs from os.path import join, exists from shutil import rmtree from tempfile import mkdtemp from pylada.vasp.files import WAVECAR from pylada.vasp import Vasp from pylada.misc import local_path Extract = namedtuple("Extract", ['directory', 'success']) a = Vasp() o = a._input['istart'] d = {'IStart': o.__class__} directory = mkdtemp() if directory in ['/tmp/test', '/tmp/test/']: if exists(directory): rmtree(directory) makedirs(directory) try: assert a.istart == 'auto' assert o.output_map(vasp=a, outdir=directory)['istart'] == '0' assert eval(repr(o), d).value == 'auto' assert loads(dumps(o)).value == 'auto' restartdir = join(directory, 'restart') local_path(restartdir).ensure(dir=True) with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') # do not copy if not successful a.restart = Extract(restartdir, False) assert o.output_map(vasp=a, outdir=directory)['istart'] == '0' assert not exists(join(directory, 'WAVECAR')) # do not copy if file is empty a.restart = Extract(restartdir, True) with open(join(restartdir, WAVECAR), 'w') as file: pass assert o.output_map(vasp=a, outdir=directory)['istart'] == '0' assert not exists(join(directory, 'WAVECAR')) # now should copy assert a.istart == 'auto' with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') assert o.output_map(vasp=a, outdir=directory)['istart'] == '1' assert exists(join(directory, 'WAVECAR')) # check it copies only latest file. with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') file.flush() with open(join(restartdir, WAVECAR), 'r') as file: pass sleep(1.5) with open(join(directory, WAVECAR), 'w') as file: file.write('hello world') with open(join(directory, WAVECAR), 'r') as file: pass assert o.output_map(vasp=a, outdir=directory)['istart'] == '1' assert exists(join(directory, 'WAVECAR')) with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() == 'hello world' sleep(0.2) with open(join(restartdir, WAVECAR), 'w') as file: file.write('hello') assert o.output_map(vasp=a, outdir=directory)['istart'] == '1' assert exists(join(directory, 'WAVECAR')) with open(join(directory, WAVECAR), 'r') as file: assert file.read().rstrip().lstrip() == 'hello' # check if scratch is required remove(join(directory, WAVECAR)) a.istart = 'scratch' assert a.istart == 'scratch' assert o.output_map(vasp=a, outdir=directory)['istart'] == '0' assert eval(repr(o), d).value == 'scratch' assert loads(dumps(o)).value == 'scratch' finally: if directory not in ['/tmp/test', '/tmp/test/'] and exists(directory): rmtree(directory)
def completer(self, event): """ Completer for %record magic function. """ from pylada.misc import local_path from pickle import load from os.path import isdir, exists result = [] data = event.line.split()[1:] if (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--n") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--n") \ or (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--namespace") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--namespace"): return [ key for key, value in self.api.user_ns.items() if key[0] != '_' and hasattr(value, '__dict__') ] if (len(event.symbol) == 0 and len(data) > 0 and data[-1] == "--file") \ or (len(event.symbol) > 0 and len(data) > 1 and data[-2] == "--file"): other = event.symbol string = '%mglob "cont:This is a record." {0}*'.format(other) result = [u for u in self.api.magic(string)] string = '%mglob dir:{0}*'.format(other) result.extend([u for u in self.api.magic(string)]) if isdir(other) and other[-1] != '/': string = '%mglob "cont:This is a record." {0}/*'.format(other) result.extend([u for u in self.api.magic(string)]) return result if '--file' not in data: result.append('--file') options = {'--list', '--view', '--load', '--remove', '--update'} if '-n' in data or '--namespace' in data and '--load' not in data: result.append('--load') elif '--load' in data and '-n' not in data and '--namespace' not in data: result.append('--namespace') elif len(options.intersection(set(data))) == 0: result.extend([ '--list', '--view', '--load', '--remove', '--namespace', '--update' ]) if len(set(['--load', '--remove', '--view']).intersection(set(data))) != 0: path = '.pylada_record' known = [u for u in data] if '--file' in data: index = data.index('--file') assert len(data) > index + 1 path = str(local_path(data[index + 1])) known.pop(index + 1) if exists(path): with open(path) as file: keys = load(file) if '--namespace' in known: index = known.index('--namespace') if len(known) > index + 1: known.pop(index + 1) if '-n' in known: index = known.index('-n') if len(known) > index + 1: known.pop(index + 1) result.extend(keys - set(known)) else: result.extend([u for u in self.api.user_ns.keys() if u[0] != '_']) return result