def test_single_pseudo_from_dict_deprecated(): """Check that from_dict still works as intented""" with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: pseudo = PseudopotentialData.from_lines([line for line in fhandle]) asdict = pseudo.dict() with pytest.deprecated_call(): reloaded = PseudopotentialData.from_dict(asdict) assert reloaded == pseudo
def test_single_pseudo_parse_obj_nlcc_empty_default(): """Check that for local/non_local data we can also use the abbrev 'coeffs' for loading""" with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: pseudo = PseudopotentialData.from_lines([line for line in fhandle]) assert pseudo.nlcc is not None asdict = pseudo.dict() asdict.pop("nlcc") reloaded = PseudopotentialData.parse_obj(asdict) assert reloaded.nlcc == []
def test_single_pseudo_parse_obj_aliased(): """Check that for local/non_local data we can also use the abbrev 'coeffs' for loading""" with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: pseudo = PseudopotentialData.from_lines([line for line in fhandle]) assert pseudo.local.coefficients asdict = pseudo.dict() asdict["local"]["coeffs"] = asdict["local"].pop("coefficients") reloaded = PseudopotentialData.parse_obj(asdict) assert reloaded == pseudo
def _dict2pseudodata(data: Dict[str, Any]) -> PseudopotentialData: obj = { k: v for k, v in data.items() if k not in ("name", "tags", "version") } obj["identifiers"] = obj.pop("aliases") return PseudopotentialData.parse_obj(obj)
def _pseudodata2dict(data: PseudopotentialData) -> Dict[str, Any]: """ Convert a PseudopotentialData to a compatible dict with: * Decimals replaced by strings * the required attrs set on the root * the key "coefficients" replaced with "coeffs" """ pseudo_dict = data.dict(by_alias=True) stack = [pseudo_dict] while stack: current = stack.pop() for key, val in current.items(): if isinstance(val, dict): stack.append(val) elif isinstance(val, Decimal): current[key] = str(val) elif isinstance(val, list) and val and isinstance(val[0], dict): stack += val elif isinstance(val, list) and val and isinstance(val[0], Decimal): current[key] = [str(v) for v in val] pseudo_dict["aliases"] = sorted(pseudo_dict.pop("identifiers"), key=lambda i: -len(i)) pseudo_dict["name"] = pseudo_dict["aliases"][0] pseudo_dict["tags"] = pseudo_dict["name"].split("-") return pseudo_dict
def test_single_pseudo_from_dict_type_map_deprecated(): """Check that from_dict still works as intented with the type_map and its likely only use case""" with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: pseudo = PseudopotentialData.from_lines([line for line in fhandle]) asdict = pseudo.dict() asdict["local"]["coeffs"] = asdict["local"].pop("coefficients") def rename(data): data["coefficients"] = data.pop("coeffs") return data with pytest.deprecated_call(): reloaded = PseudopotentialData.from_dict(asdict, type_hooks={PseudopotentialDataLocal: rename}) assert reloaded == pseudo
def test_single_pseudo_import(): with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: pseudo = PseudopotentialData.from_lines([line for line in fhandle]) assert pseudo.element == "Cl" assert pseudo.n_el == [2, 5] assert len(pseudo.local.coefficients) == 1 assert len(pseudo.non_local) == 2 assert pseudo.non_local[0].nproj == 2 assert pseudo.non_local[1].nproj == 1
def from_cp2k(cls, fhandle, filters=None, duplicate_handling="ignore", ignore_invalid=False): """ Constructs a list with pseudopotential objects from a Pseudopotential in CP2K format :param fhandle: open file handle :param filters: a dict with attribute filter functions :param duplicate_handling: how to handle duplicates ("ignore", "error", "new" (version)) :param ignore_invalid: whether to ignore invalid entries silently :rtype: list """ from cp2k_input_tools.pseudopotentials import PseudopotentialData if not filters: filters = {} def matches_criteria(pseudo): return all( fspec(pseudo[field]) for field, fspec in filters.items()) def exists(pseudo): try: cls.get(pseudo["element"], pseudo["name"], match_aliases=False) except NotExistent: return False return True pseudos = [ p for p in (_pseudodata2dict(p) for p in PseudopotentialData.datafile_iter( fhandle, keep_going=ignore_invalid)) if matches_criteria(p) ] if duplicate_handling == "ignore": # simply filter duplicates pseudos = [p for p in pseudos if not exists(p)] elif duplicate_handling == "error": for pseudo in pseudos: try: latest = cls.get(pseudo["element"], pseudo["name"], match_aliases=False) except NotExistent: pass else: raise UniquenessError( f"Gaussian Pseudopotential already exists for" f" element={pseudo['element']}, name={pseudo['name']}: {latest.uuid}" ) elif duplicate_handling == "new": for pseudo in pseudos: try: latest = cls.get(pseudo["element"], pseudo["name"], match_aliases=False) except NotExistent: pass else: pseudo["version"] = latest.version + 1 else: raise ValueError( f"Specified duplicate handling strategy not recognized: '{duplicate_handling}'" ) return [cls(**p) for p in pseudos]
def test_single_pseudo_roundtrip(): with (TEST_DIR / "inputs" / "GTH_POTENTIALS.Cl").open() as fhandle: lines = [line.rstrip() for line in fhandle] pseudo = PseudopotentialData.from_lines(lines) assert list(pseudo.cp2k_format_line_iter()) == lines