def run(args): """Runs the matdb setup and cleanup to produce database files. """ if args is None: return cmd = args["cmd"] print(cmd) keyword = cmd[0].strip() print(keyword) if keyword == "calc-grade": touch("state.mvs") touch("temp1.cfg") elif keyword == "select-add": template_root = path.join(_get_reporoot(), "tests", "fitting", "files") touch("new_training.cfg") # src = path.join(template_root,"mtp_new_training.cfg") # dest = "new_training.cfg" # copyonce(src, dest) elif keyword == "convert-cfg": template_root = path.join(_get_reporoot(), "tests", "mtp", "training") for i in range(1, 11): src = path.join(template_root, "POSCAR{0}".format(i)) dest = "POSCAR{0}".format(i) copyonce(src, dest)
def Act(tmpdir): target = relpath("./tests/AgPd/matdb.yml") dbdir = str(tmpdir.join("active_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") seed_root = path.join(dbdir, "seed") if not path.isdir(seed_root): mkdir(seed_root) for i in range(1, 4): cfg_target = path.join(seed_root, "Pd{0}".format(i)) cfg_source = path.join(_get_reporoot(), "tests", "database", "files", "Pd", "POSCAR{0}".format(i)) copyonce(cfg_source, cfg_target) cntrl = Controller(target, dbdir) db = Database("active", dbdir, cntrl, [{"type": "active.Active"}], {}, 0) tcntrl = TController(db=db, root=dbdir, fits={}) dbargs = {"root": dbdir, "parent": db, "calculator": tcntrl.db.calculator} result = Active(**dbargs) return result
def test_prot_to_cfg(): """Tests the conversion of a prototype structure to a cfg file. """ from matdb.fitting.mtp import _prot_to_cfg from matdb.utility import _get_reporoot, touch, chdir from os import path, remove import tarfile template_root = path.join(_get_reporoot(), "matdb", "templates") if not path.isdir(path.join(template_root, "uniqueUnaries")): with chdir(template_root): tarf = "prototypes.tar.gz" tar = tarfile.open(tarf, "r:gz") tar.extractall() tar.close() source = path.join(template_root, "uniqueUnaries", "A10_POSCAR.orig") species = ["Al"] relax_file = "relax.cfg" type_map = {0:0} root = "." min_atoms = 1 max_atoms = None touch(relax_file) _prot_to_cfg(source, species, relax_file, type_map, root, min_atoms, max_atoms) assert path.isfile(relax_file) lc = 0 with open(relax_file, "r") as f: for line in f: lc += 1 assert lc == 12 source = path.join(template_root, "uniqueBinaries", "b31_POSCAR.orig") species = ["Al", "Cu"] relax_file = "relax.cfg" type_map = {0:0, 1:1} root = "." min_atoms = 1 max_atoms = 4 _prot_to_cfg(source, species, relax_file, type_map, root, min_atoms, max_atoms) lc = 0 with open(relax_file, "r") as f: for line in f: lc += 1 assert lc == 12 remove(relax_file)
def Pd(tmpdir): target = relpath("./tests/Pd/matdb.yml") dbdir = str(tmpdir.join("manual_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) seed_root = path.join(dbdir, "seed") if not path.isdir(seed_root): mkdir(seed_root) for i in range(1, 4): cfg_target = path.join(seed_root, "Pd{0}".format(i)) cfg_source = path.join(_get_reporoot(), "tests", "database", "files", "Pd", "POSCAR{0}".format(i)) copyonce(cfg_source, cfg_target) target = path.join(dbdir, "matdb") cntrl = Controller(target, dbdir) return cntrl
def Pd_not_extractable(tmpdir): target = relpath("./tests/Pd/matdb_not_extractable.yml") dbdir = str(tmpdir.join("manual_not_extractale_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) seed_root = path.join(dbdir, "seed") if not path.isdir(seed_root): mkdir(seed_root) cfg_target = path.join(seed_root, "Pd") cfg_source = path.join(_get_reporoot(), "tests", "database", "files", "Pd", "POSCAR1") copyonce(cfg_source, cfg_target) target = path.join(dbdir, "matdb") cntrl = Controller(target, dbdir) # these 3 lines are just added to cover dbargs["calculator"] not None in __init__ db = Database("phonon", dbdir, cntrl, [{"type": "simple.Manual"}], {}, 0) dbargs = {"root": dbdir, "parent": db, "calculator": cntrl.calculator} mdb = Manual(extractable=False, **dbargs) return cntrl
def create_to_relax(setup_args): """Creates the to-relax.cfg file from the passed in args dictionary. Args: setup_args (dict): A dictionary containing the arguments needed to construct the potential. """ args = setup_args["phenum_args"] species = np.unique(setup_args["species"]) crystals = setup_args["crystals"] min_atoms = setup_args["min_atoms"] max_atoms = setup_args["max_atoms"] root = setup_args["root"] touch(args["outfile"]) for crystal in crystals: prot_map = { 0: "uniqueUnaries", 1: "uniqueBinaries", 2: "uniqueTernaries" } if crystal == "prototypes": # The prototypes are saved into the file prototypes.tar.gz, if # this is the first time prototypes has been run we need to unpack it. template_root = path.join(_get_reporoot(), "matdb", "templates") if not path.isdir(path.join(template_root, "uniqueUnaries")): with chdir(template_root): tarf = "prototypes.tar.gz" tar = tarfile.open(tarf, "r:gz") tar.extractall() tar.close() for size in range(len(species)): cand_path = path.join(template_root, prot_map[size]) structures = glob("{0}/*".format(cand_path)) perms = [list(i) for i in permutations(species, r=size + 1)] for fpath, perm in product(structures, perms): type_map = {} for i, s in enumerate(species): if s in perm: type_map[perm.index(s)] = i _prot_to_cfg(fpath, perm, args["outfile"], type_map, root, min_atoms, max_atoms) else: # eventually we'll want to replace this with an actual # enumeration over the options the user specifies. infile = path.join( _get_reporoot(), "matdb", "templates", "struct_enum.out_{0}_{1}".format(len(species), crystal)) expected_min_atoms = 1 if crystal == "hcp": min_atoms = 2 expected_min_atoms = 2 if min_atoms != expected_min_atoms or max_atoms is not None: with open(infile, "r") as f: min_num = None max_num = None last_num = 1 past_start = False for line in f: if line.split()[0] == "start": past_start = True continue if past_start: data = line.strip().split() lab = data[-2] last_num = int(data[0]) if len(lab) == min_atoms and min_num is None: min_num = int(data[0]) if len(lab) > max_atoms and max_num is None: max_num = int(data[0]) break # In case in the input file, there is no configuration # that has the number of atoms bigger than max_atoms, # the max_num will be set to the number in the last # line. if max_num is None: max_num = last_num args["structures"] = range(min_num, max_num) args["input"] = infile _make_structures(args)
def __init__(self, name="prototype", structures=None, ran_seed=None, permutations=None, **dbargs): self.name = name self.seeded = False dbargs["prefix"] = "P" dbargs["cls"] = Prototypes if "Prototypes" not in dbargs['root']: from os import mkdir new_root = path.join(dbargs['root'], "Prototypes") if not path.isdir(new_root): mkdir(new_root) dbargs['root'] = new_root super(Prototypes, self).__init__(**dbargs) self.in_structures = structures self.ran_seed = ran_seed self.permutations = permutations self.species = self.database.parent.species #Make sure that we override the global calculator default values with #those settings that we know are needed for good phonon calculations. calcargs = self.database.calculator.copy() if "calculator" in dbargs: if dbargs["calculator"] is not None and "name" in dbargs[ "calculator"]: calcargs.update(dbargs["calculator"]) dbargs["calculator"] = calcargs # The prototypes are saved into the file prototypes.tar.gz, if # this is the first time prototypes has been run we need to unpack it. template_root = path.join(_get_reporoot(), "matdb", "templates") if not path.isdir(path.join(template_root, "uniqueUnaries")): import tarfile with chdir(template_root): tarf = "prototypes.tar.gz" tar = tarfile.open(tarf, "r:gz") tar.extractall() tar.close() # parse the structures to make a list of paths to the source folders for the if self.ran_seed is not None: import random random.seed(self.ran_seed) self.puuids = None self._load_puuids() self.nconfigs = 0 self.structures = {} for k, v in structures.items(): if k.lower() == "unary": cand_path = path.join(template_root, "uniqueUnaries") elif k.lower() == "binary": cand_path = path.join(template_root, "uniqueBinaries") elif k.lower() == "ternary": cand_path = path.join(template_root, "uniqueTernaries") else: # pragma: no cover msg.warn( "Must specify the system size, i.e., unary, binary, or " "ternary. {} not recognized".format(k)) continue if isinstance(v, list): self.structures[k.lower()] = [] for prot in v: files = glob("{0}/*{1}*".format(cand_path, prot)) if len(files) < 1: # pragma: no cover msg.warn( "No prototypes of size {0} matched the string " "{1}".format(k, prot)) else: self.structures[k.lower()].extend(files) elif isinstance(v, str) and v == "all": files = glob("{0}/*".format(cand_path)) self.structures[k.lower()] = files elif isinstance(v, int): from random import shuffle files = glob("{0}/*".format(cand_path)) shuffle(files) keep = files[:v] self.structures[k.lower()] = keep else: #pragma: no cover msg.err( "Couldn't parse {0} structures for {1} case. Must be either " "a list of file names, 'all', or an int.".format(v, k)) if self.permutations is not None and k.lower( ) in self.permutations.keys(): self.nconfigs += len(self.structures[k.lower()]) * len( self.permutations[k.lower()]) else: if k.lower() == "unary": self.nconfigs += len(self.structures[k.lower()]) * 3 elif k.lower() == "binary" or k.lower() == "ternary": self.nconfigs += len(self.structures[k.lower()]) * 6 else: #pragma: no cover continue
def test_create_to_relax(): """Tests the creation of the to_relax_file. """ from matdb.fitting.mtp import create_to_relax from matdb.utility import _get_reporoot from os import remove, path import shutil template_root = path.join(_get_reporoot(), "matdb", "templates") if path.isdir(path.join(template_root, "uniqueUnaries")): shutil.rmtree(path.join(template_root, "uniqueUnaries"), ignore_errors=True) shutil.rmtree(path.join(template_root, "uniqueBinaries"), ignore_errors=True) shutil.rmtree(path.join(template_root, "uniqueTernaries"), ignore_errors=True) setup_args = {} target = "to-relax.cfg" if path.isfile(target): remove(target) setup_args["phenum_args"] = {"config":"t", "species": ["Al", "Cu"], "structures": "all", "debug": False, "example": False, "displace":0.0, "mink":True, "outfile":target, "verbose": None, "rattle":0.0, "mapping": None} setup_args["species"] = ["Al", "Cu"] setup_args["crystals"] = ["fcc"] setup_args["min_atoms"] = 1 setup_args["max_atoms"] = 2 setup_args["root"] = "." create_to_relax(setup_args) struct_count = 0 with open(target,"r") as f: for line in f: if "BEGIN_CFG" in line: struct_count += 1 assert struct_count == 4 remove(target) setup_args["crystals"] = ["fcc", "prototypes", "hcp"] create_to_relax(setup_args) struct_count = 0 with open(target,"r") as f: for line in f: if "BEGIN_CFG" in line: struct_count += 1 assert struct_count == 141 remove(target) setup_args["crystals"] = ["fcc"] setup_args["min_atoms"] = 12 setup_args["max_atoms"] = 14 create_to_relax(setup_args) struct_count = 0 with open(target,"r") as f: for line in f: if "BEGIN_CFG" in line: struct_count += 1 assert struct_count == 7139 remove(target)
def test_command_functions(mtpdb): """All the commands are iterative, so we'll have to test them one after the other. """ #first build the database directory and the initial database of #structures. from matdb.utility import copyonce, _get_reporoot, touch from os import path, mkdir, remove, rename from matdb.atoms import Atoms seed_root = path.join(mtpdb.root, "seed") mkdir(seed_root) templates = path.join(_get_reporoot(), "tests", "mtp", "training") for i in range(1,11): target = path.join(seed_root, "vasp.{0}".format(i)) source = path.join(templates, "POSCAR{0}".format(i)) copyonce(source, target) mtpfit = mtpdb.trainers.fits['CoWV_mtp'].sequences['CoWV_mtp'].steps['mtp'] cntrl_root = mtpdb.root db_root = path.join(cntrl_root, "Manual", "test.manual") mtpdb.setup() files = ["OUTCAR{}", "CONTCAR{}"] for i in range(1,11): target = path.join(db_root, "vasp.{0}".format(i), "S1.1") for f in files: copyonce(path.join(templates, f.format(i)), path.join(target, f.format(''))) mtpdb.extract() touch(path.join(mtpfit.root, "new_training.cfg")) touch(path.join(mtpfit.root, "relaxed.cfg")) # With the initial database setup we can now run the mtp commands. # First test the initial training setup script cmd_template = mtpfit.command() target = path.join(mtpfit.root, "status.txt") bc = path.join(mtpfit.root, "status.txt_train") copyonce(target,bc) assert path.isfile(target) with open(target, "r") as f: line = f.read() assert line.strip() == "relax_setup 1 0" assert path.isfile(path.join(mtpfit.root, "relax.ini")) assert path.isfile(path.join(mtpfit.root, "pot.mtp")) assert cmd_template == mtpfit._train_template() # Now we setup for the test of the relaxation_setup copyonce(path.join(mtpfit.root, "pot.mtp"), path.join(mtpfit.root, "Trained.mtp_")) cmd_template = mtpfit.command() assert "matdb_mtp_to_relax.py" in cmd_template with open(target, "r") as f: line = f.read() assert line.strip() == "relax 1 0" rename(bc, target) copyonce(target,bc) copyonce(path.join(mtpfit.root, "pot.mtp"), path.join(mtpfit.root, "Trained.mtp_")) touch(path.join(mtpfit.root, "unrelaxed.cfg")) mtpfit.use_unrelaxed = True cmd_template = mtpfit.command() assert cmd_template == mtpfit._relax_template() with open(target, "r") as f: line = f.read() assert line.strip() == "select 1 0" mtpfit.use_unrelaxed = False rename(bc, target) copyonce(path.join(mtpfit.root, "pot.mtp"), path.join(mtpfit.root, "Trained.mtp_")) touch(path.join(mtpfit.root, "candidate.cfg")) cmd_template = mtpfit.command() assert cmd_template == mtpfit._relax_template() with open(target, "r") as f: line = f.read() assert line.strip() == "select 1 0" # Now we can test the select step for i in range(72): touch(path.join(mtpfit.root, "candidate.cfg_{0}".format(i))) cmd_template = mtpfit.command() assert path.isfile(path.join(mtpfit.root, "candidate.cfg")) with open(target, "r") as f: line = f.read() assert line.strip() == "add 1 0"
def test_train_setup(mtpdb): """Tests the mtp training setup. """ #test make_train_cfg #first build the database directory. from matdb.utility import copyonce, _get_reporoot from os import path, mkdir, remove from matdb.atoms import Atoms seed_root = path.join(mtpdb.root, "seed") mkdir(seed_root) templates = path.join(_get_reporoot(), "tests", "mtp", "training") for i in range(1,11): target = path.join(seed_root, "vasp.{0}".format(i)) source = path.join(templates, "POSCAR{0}".format(i)) copyonce(source, target) mtpfit = mtpdb.trainers.fits['CoWV_mtp'].sequences['CoWV_mtp'].steps['mtp'] cntrl_root = mtpdb.root db_root = path.join(cntrl_root, "Manual", "test.manual") mtpdb.setup() files = ["OUTCAR{}", "CONTCAR{}"] for i in range(1,11): target = path.join(db_root, "vasp.{0}".format(i), "S1.1") for f in files: copyonce(path.join(templates, f.format(i)), path.join(target, f.format(''))) mtpdb.extract() mtpfit._make_train_cfg(1) assert path.isfile(path.join(mtpfit.root, "train.cfg")) struct_count = 0 with open(path.join(mtpfit.root, "train.cfg"),"r") as f: for line in f: if "BEGIN_CFG" in line: struct_count += 1 assert struct_count == 10 new_configs = [] for i in range(1,11): source = path.join(templates, "POSCAR{0}".format(i)) new_configs.append(Atoms(source)) mtpfit.active.add_configs(new_configs, 2) mtpfit.active.setup() act_root = path.join(mtpdb.root, "Active", "active.CoWV_mtp") files = ["OUTCAR{}", "CONTCAR{}"] for i in range(1,11): target = path.join(act_root, "Ac.{0}".format(i)) for f in files: copyonce(path.join(templates, f.format(i)), path.join(target, f.format(''))) # This is trying to manipulate an NOT extractable structure target = path.join(act_root, "Ac.{0}".format(3), "OUTCAR") remove(target) source = path.join(_get_reporoot(), "tests", "files", "VASP", "OUTCAR_incomplete") copyonce(source, target) mtpfit.active.last_iteration = None mtpfit._make_train_cfg(2) assert path.isfile(path.join(mtpfit.root, "train.cfg")) struct_count = 0 with open(path.join(mtpfit.root, "train.cfg"),"r") as f: for line in f: if "BEGIN_CFG" in line: struct_count += 1 assert struct_count == 19 mtpfit.active.last_iteration = None remove(mtpfit.active.iter_file) with pytest.raises(IOError): mtpfit._make_train_cfg(2)