def Pd(tmpdir): from matdb.utility import relpath, copyonce from matdb.database import Controller from os import mkdir, symlink, remove, path target = relpath("./tests/Pd/matdb.yml") dbdir = str(tmpdir.join("pd_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") #We need to copy the POSCAR over from the testing directory to the temporary #one. from shutil import copy POSCAR = relpath("./tests/Pd/POSCAR") mkdir(path.join(dbdir, "seed")) copy(POSCAR, path.join(dbdir, "seed", "Pd")) # the source file `matdb.yml` linked to might be gone, that left `matdb.yml` not an valid "file" # we need to get rid if it anyway try: remove("matdb.yml") except: pass symlink("{}.yml".format(target), "matdb.yml") result = Controller("matdb", dbdir) remove("matdb.yml") result = Controller(target, dbdir) return result
def AgCu(tmpdir): """Test the functionality of the substitution group for a small seed configuration where the number of possible random combinations is limited and repition is more likely. Attributes: atoms_seed(matdb.atoms.Atoms): The seed atoms objech configuration for db generation. """ from matdb.utility import relpath from matdb.database import Controller from shutil import copy target = relpath("./tests/AgCu/matdb.yml") dbdir = str(tmpdir.join("agcu_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") # We need to copy the POSCAR from the testing directory to tempdir. POSCAR = relpath("./tests/AgCu/Ag1Cu5") mkdir(path.join(dbdir, "seed")) copy(POSCAR, path.join(dbdir, "seed", "Ag1Cu5")) if path.isfile("matdb.yml"): remove("matdb.yml") symlink("{}.yml".format(target), "matdb.yml") result = Controller(target, dbdir) return result
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 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 Pd_no_seeds(tmpdir): target = relpath("./tests/Pd/matdb_no_seeds.yml") dbdir = str(tmpdir.join("manual_no_seeds_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") cntrl = Controller(target, dbdir) return cntrl
def CoNiTi(tmpdir): from matdb.utility import relpath, copyonce from matdb.database import Controller from os import mkdir, symlink, remove target = relpath("./tests/files/CoNiTi.yml") dbdir = str(tmpdir.join("coniti_db")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") result = Controller(target, dbdir) return result
def mtpdb(tmpdir): from matdb.utility import relpath, reporoot, copyonce from matdb.database import Controller from os import mkdir, path target = relpath("./tests/mtp/CoWV.yml") dbdir = str(tmpdir.join("mlp_tests")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir,"matdb") cntrl = Controller(target, tmpdir=dbdir) return cntrl
def test_copyonce(): """Tests the copyonce method in utility. """ from matdb.utility import copyonce, touch from os import remove, path touch("temp1.txt") copyonce("temp1.txt","temp2.txt") assert path.isfile("temp2.txt") remove("temp1.txt") remove("temp2.txt")
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") 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 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_split(tmpdir): from matdb.utility import relpath, copyonce from matdb.database import Controller from os import mkdir, path target = relpath("./tests/Pd/matdb_split.yml") dbdir = str(tmpdir.join("pd_db_splits")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") from shutil import copy POSCAR = relpath("./tests/Pd/POSCAR") mkdir(path.join(dbdir, "seed")) copy(POSCAR, path.join(dbdir, "seed", "Pd-1")) copy(POSCAR, path.join(dbdir, "seed", "Pd-2")) copy(POSCAR, path.join(dbdir, "seed", "Pd-3")) copy(POSCAR, path.join(dbdir, "seed", "Pd-4")) copy(POSCAR, path.join(dbdir, "seed", "Pd-5")) result = Controller(target, dbdir) return result
def Pd_copy(tmpdir): from matdb.utility import relpath, copyonce from matdb.database import Controller from os import path, remove, mkdir target = relpath("./tests/Pd/matdb_copy.yml") dbdir = str(tmpdir.join("pd_db_copy")) mkdir(dbdir) copyonce(target, path.join(dbdir, "matdb.yml")) target = path.join(dbdir, "matdb") from shutil import copy POSCAR = relpath("./tests/Pd/POSCAR") if path.isfile("matdb_copy.yml"): remove("matdb_copy.yml") result = Controller(target, dbdir) mkdir(path.join(dbdir, "seed")) copy(POSCAR, path.join(dbdir, "seed", "Pd")) result = Controller(target, dbdir) return result
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 html(data, folder, plot="scatter", subplot_kw=None, gridspec_kw=None, fig_kw=None, plot_kw=None, titles=None, ncols=3, font=None): """Creates an HTML interactive plot package in the specified directory. Args: data (dict): keys are point names; values are `dict` with a `location` key specifying the 2D tuple `(x, y)` where the point should be plotted. The `index` key specifies its order in the plot. Additional keys of image types and :class:`PointDetailImage` values provide data for plotting auxiliary images. plot (str): type of plot to perform; one of the plot types on :class:`matplotlib.axes._subplots.AxesSubplot`. subplot_kw (dict): keywords passed to the :meth:`~matplotlib.figure.Figure.add_subplot` call used to create each subplot. gridspec_kw (dict): keywords passed to the :class:`~matplotlib.gridspec.GridSpec` constructor used to create the grid the subplots are placed on. fig_kw (dict): keyword arguments are passed to the :func:`~matplotlib.pyplot.figure` call. plot_kw (dict): keyword arguments passed to the particular plot method. titles (dict): keys are image types in `data`; values are `str` titles to display for each of the image types. ncols (int): number of columns for the grid of detail images. font (dict): key-value pairs for the :func:`matplotlib.rc` configuration for `font`. Examples: This is a simple example of what `data` might look like. .. code-block:: python data = { "gp_2b": { "location": (0.2, 1.4), "index": 0, "potato": PointDetailImage(), "EvsV": PointDetailImage() }, "gp_3b": { "location": (0.82, 0.75), "index": 1, "potato": PointDetailImage(), "EvsV": PointDetailImage() } } """ import matplotlib if font is None: font = {'size' : 22} matplotlib.rc('font', **font) #Sort the data by index. sdata = sorted(data.items(), key=(lambda d: d[1]["index"])) #Next, compile lists of URLs to use for each of the plot types. first = next(data.itervalues()) imgtypes = [k for k in first.keys() if k not in ["location", "index"]] images = {k: [] for k in imgtypes} names, x, y = [], [], [] for name, detail in sdata: for img in imgtypes: images[img].append(detail[img].url) names.append(name) x.append(detail["location"][0]) y.append(detail["location"][1]) import matplotlib.pyplot as plt import numpy as np import mpld3 if fig_kw is None: fig_kw = {} figure, axes = plt.subplots(subplot_kw=subplot_kw, gridspec_kw=gridspec_kw, **fig_kw) #Grab the particular plot type that the user wants to make, then #generate the figure. We need to compile the x and y arrays from the #location information in each point. if plot_kw is None:# pragma: no cover plot_kw = {} if "s" not in plot_kw: plot_kw["s"] = 300 plotter = getattr(axes, plot) points = plotter(np.array(x), np.array(y), **plot_kw) from matdb.plotting.matd3 import ImagesAtPoint plugiap = ImagesAtPoint(points, names, ncols, titles, **images) mpld3.plugins.connect(figure, plugiap) #Next, copy the JS and CSS dependencies over from the package data into the #directory. from matdb.utility import relpath, copyonce folder = path.abspath(path.expanduser(folder)) js = relpath("matdb/js/imagepoint.js") copyonce(js, path.join(folder, "imagepoint.js")) css = relpath("matdb/css/imagepoint.css") copyonce(css, path.join(folder, "imagepoint.css")) target = path.join(folder, "index.html") with open(target, 'w') as f: mpld3.save_html(figure, f)
def _enumerate(self, dind, recurse, home): """Performs the enumeration using phenum and creates the files in the correct folder for each system enumerated. Args: dind (int): The number of configs found so far. recurse (int): The number of times we've attempted to find a unique set of enumerations over the same range. home (str): The home directory. """ _enum_out({ "input": "enum.in", "outfile": "enum.out", "seed": self.ran_seed if self.ran_seed is None else self.ran_seed + dind + recurse, "lattice": "lattice.in", "distribution": ["all", str(self.nconfigs)], "super": self.keep_supers, "sizes": None, "savedist": None, "filter": None, "acceptrate": None }) remove("enum.in") [remove(f) for f in listdir('.') if f.startswith("polya.")] # extract the POSCARS euids = _make_structures( { "structures": None, "input": "enum.out", "species": self.species, "rattle": self.rattle, "mink": "t", "outfile": "vasp.{}", "displace": self.displace, "config": "f", "remove_zeros": "f" }, return_euids=True) # Now we need to create the folder for each system we've enumerated if self.euids is None: self.euids = [] for count, dposcar in enumerate(glob("vasp.*")): if dind == self.nconfigs: break elif euids[count].hexdigest() not in self.euids: dind += 1 datoms = Atoms(dposcar, format="vasp") with chdir(home): self.create(datoms, cid=dind) copyonce(dposcar, path.join(self.configs[dind], "POSCAR_orig")) self.index[str(euids[count].hexdigest())] = self.configs[dind] self.euids.append(str(euids[count].hexdigest())) [remove(f) for f in listdir('.') if f.startswith("vasp.")] return dind
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)