diff --git a/castep_outputs/cli/args.py b/castep_outputs/cli/args.py index e7cb5f7..6e3fa11 100644 --- a/castep_outputs/cli/args.py +++ b/castep_outputs/cli/args.py @@ -23,7 +23,7 @@ AP.add_argument("seedname", nargs=argparse.REMAINDER, help="Seed name for data") AP.add_argument("-V", "--version", action="version", version="%(prog)s v0.1") AP.add_argument("-L", "--log", help="Verbose output", - choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'), default="WARNING") + choices=("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"), default="WARNING") AP.add_argument("-o", "--output", help="File to write output, default: screen", default=None) AP.add_argument("-f", "--out-format", help="Output format", choices=SUPPORTED_FORMATS, default="json") diff --git a/castep_outputs/cli/castep_outputs_main.py b/castep_outputs/cli/castep_outputs_main.py index 2e0f8cc..1482540 100644 --- a/castep_outputs/cli/castep_outputs_main.py +++ b/castep_outputs/cli/castep_outputs_main.py @@ -43,7 +43,7 @@ def parse_single(in_file: str | Path | TextIO, if isinstance(in_file, io.TextIOBase): data = parser(in_file) elif isinstance(in_file, Path): - with in_file.open(mode='r', encoding="utf-8") as file: + with in_file.open(mode="r", encoding="utf-8") as file: data = parser(file) if out_format == "json" or testing: @@ -80,7 +80,7 @@ def parse_all(output: Path | None = None, out_format: OutFormats = "json", elif isinstance(output, io.TextIOBase): file_dumper(data, output) else: - with output.open('a+', encoding='utf-8') as out_file: + with output.open("a+", encoding="utf-8") as out_file: file_dumper(data, out_file) diff --git a/castep_outputs/parsers/bands_file_parser.py b/castep_outputs/parsers/bands_file_parser.py index 4f691c8..5ef199c 100644 --- a/castep_outputs/parsers/bands_file_parser.py +++ b/castep_outputs/parsers/bands_file_parser.py @@ -27,38 +27,38 @@ def parse_bands_file(bands_file: TextIO) -> dict[str, Any]: for line in bands_file: if line.startswith("K-point"): if qdata: - fix_data_types(qdata, {'qpt': float, - 'weight': float, - 'spin_comp': int, - 'band': float, - 'band_up': float, - 'band_dn': float, + fix_data_types(qdata, {"qpt": float, + "weight": float, + "spin_comp": int, + "band": float, + "band_up": float, + "band_dn": float, }) - bands_info['bands'].append(qdata) + bands_info["bands"].append(qdata) _, _, *qpt, weight = line.split() - qdata = {'qpt': qpt, 'weight': weight, 'spin_comp': None, 'band': []} + qdata = {"qpt": qpt, "weight": weight, "spin_comp": None, "band": []} elif line.startswith("Spin component"): - qdata['spin_comp'] = line.split()[2] - if qdata['spin_comp'] != "1": - qdata['band_up'] = qdata.pop('band') + qdata["spin_comp"] = line.split()[2] + if qdata["spin_comp"] != "1": + qdata["band_up"] = qdata.pop("band") if "band_dn" not in qdata: qdata["band_dn"] = [] elif re.match(rf"^\s*{REs.FNUMBER_RE}$", line.strip()): - if qdata['spin_comp'] != "1": - qdata['band_dn'].append(line) + if qdata["spin_comp"] != "1": + qdata["band_dn"].append(line) else: - qdata['band'].append(line) + qdata["band"].append(line) if qdata: - fix_data_types(qdata, {'qpt': float, - 'weight': float, - 'spin_comp': int, - 'band': float, - 'band_up': float, - 'band_dn': float, + fix_data_types(qdata, {"qpt": float, + "weight": float, + "spin_comp": int, + "band": float, + "band_up": float, + "band_dn": float, }) - bands_info['bands'].append(qdata) + bands_info["bands"].append(qdata) return bands_info diff --git a/castep_outputs/parsers/castep_file_parser.py b/castep_outputs/parsers/castep_file_parser.py index 5269892..5a03911 100644 --- a/castep_outputs/parsers/castep_file_parser.py +++ b/castep_outputs/parsers/castep_file_parser.py @@ -612,13 +612,13 @@ def parse_castep_file(castep_file_in: TextIO, pos = to_type(match.group("x", "y", "z"), float) weight = float(match["weight"]) - curr_run["initial_positions"][(spec, idx)] = {'pos': pos, 'weight': weight} + curr_run["initial_positions"][(spec, idx)] = {"pos": pos, "weight": weight} elif match := REs.MIXTURE_LINE_2_RE.search(line): spec = match["spec"].strip() weight = float(match["weight"]) - curr_run["initial_positions"][(spec, idx)] = {'pos': pos, 'weight': weight} + curr_run["initial_positions"][(spec, idx)] = {"pos": pos, "weight": weight} elif block := Block.from_re(line, castep_file, "Fractional coordinates of atoms", @@ -1685,7 +1685,7 @@ def _process_born(block: Block) -> dict[AtomIndex, ThreeByThreeMatrix]: for line in block: if match := REs.BORN_RE.match(line): val = match.groupdict() - label = val.pop('label') + label = val.pop("label") if label is not None: val["spec"] = f"{val['spec']} [{label}]" @@ -1861,7 +1861,7 @@ def _process_memory_est(block: Block) -> dict[str, MemoryEst]: def _process_phonon_sym_analysis(block: Block) -> PhononSymmetryReport: - accum: PhononSymmetryReport = {'title': '', 'mat': ()} + accum: PhononSymmetryReport = {"title": "", "mat": ()} accum["title"] = normalise_string(next(block).split(":")[1]) next(block) accum["mat"] = tuple(parse_int_or_float(numbers) diff --git a/castep_outputs/parsers/cell_param_file_parser.py b/castep_outputs/parsers/cell_param_file_parser.py index 5a5b93d..56aaf9f 100644 --- a/castep_outputs/parsers/cell_param_file_parser.py +++ b/castep_outputs/parsers/cell_param_file_parser.py @@ -192,8 +192,8 @@ def _parse_symops(block: Block) -> list[dict[str, ThreeByThreeMatrix | ThreeVect for line in block if (numbers := REs.FLOAT_RAT_RE.findall(line))] - accum = [{'r': tmp[i:i+3], - 't': tmp[i+3]} + accum = [{"r": tmp[i:i+3], + "t": tmp[i+3]} for i in range(0, len(tmp), 4)] return accum diff --git a/castep_outputs/parsers/efield_file_parser.py b/castep_outputs/parsers/efield_file_parser.py index abaa578..91ab9ce 100644 --- a/castep_outputs/parsers/efield_file_parser.py +++ b/castep_outputs/parsers/efield_file_parser.py @@ -25,7 +25,7 @@ def parse_efield_file(efield_file: TextIO) -> dict[str, float | int]: for line in efield_file: if block := Block.from_re(line, efield_file, "BEGIN header", "END header"): - data = parse_regular_header(block, ('Oscillator Q',)) + data = parse_regular_header(block, ("Oscillator Q",)) efield_info.update(data) elif block := Block.from_re(line, efield_file, "BEGIN Oscillator Strengths", @@ -37,13 +37,13 @@ def parse_efield_file(efield_file: TextIO) -> dict[str, float | int]: block.remove_bounds(1, 2) for line in block: match = re.match(rf"\s*(?P{REs.INTNUMBER_RE})" + - labelled_floats([*(f'S{d}' for d in SND_D)]), line) + labelled_floats([*(f"S{d}" for d in SND_D)]), line) stack_dict(osc, match.groupdict()) if osc: - fix_data_types(osc, {'freq': float, - **{f'S{d}': float for d in SND_D}}) - efield_info['oscillator_strengths'].append(osc) + fix_data_types(osc, {"freq": float, + **{f"S{d}": float for d in SND_D}}) + efield_info["oscillator_strengths"].append(osc) elif block := Block.from_re(line, efield_file, "BEGIN permittivity", "END permittivity"): @@ -52,13 +52,13 @@ def parse_efield_file(efield_file: TextIO) -> dict[str, float | int]: perm = defaultdict(list) block.remove_bounds(1, 2) for line in block: - match = re.match(labelled_floats(['freq', - *(f'e_r_{d}' for d in SND_D)]), line) + match = re.match(labelled_floats(["freq", + *(f"e_r_{d}" for d in SND_D)]), line) stack_dict(perm, match.groupdict()) if perm: - fix_data_types(perm, {'freq': float, - **{f'e_r_{d}': float for d in SND_D}}) - efield_info['permittivity'].append(perm) + fix_data_types(perm, {"freq": float, + **{f"e_r_{d}": float for d in SND_D}}) + efield_info["permittivity"].append(perm) return efield_info diff --git a/castep_outputs/parsers/hug_file_parser.py b/castep_outputs/parsers/hug_file_parser.py index 61cb031..a638c91 100644 --- a/castep_outputs/parsers/hug_file_parser.py +++ b/castep_outputs/parsers/hug_file_parser.py @@ -15,7 +15,7 @@ def parse_hug_file(hug_file: TextIO) -> dict[str, list[float]]: """ Parse castep .hug file """ - cols = ('compression', 'temperature', 'pressure', 'energy') + cols = ("compression", "temperature", "pressure", "energy") data = defaultdict(list) for line in hug_file: if match := re.search(labelled_floats(cols), line): diff --git a/castep_outputs/parsers/md_geom_file_parser.py b/castep_outputs/parsers/md_geom_file_parser.py index ee2b6b2..c25dba9 100644 --- a/castep_outputs/parsers/md_geom_file_parser.py +++ b/castep_outputs/parsers/md_geom_file_parser.py @@ -28,16 +28,16 @@ def parse_md_geom_file(md_geom_file: TextIO) -> list[dict[str, float]]: steps.append(curr) curr = defaultdict(list) elif not TAG_RE.search(line): # Timestep - curr['time'] = to_type(get_numbers(line)[0], float) + curr["time"] = to_type(get_numbers(line)[0], float) elif match := ATDATTAG.match(line): ion = atreg_to_index(match) if ion not in curr: curr[ion] = {} - curr[ion][match.group('tag')] = to_type([*(match.group(d) for d in FST_D)], float) + curr[ion][match.group("tag")] = to_type([*(match.group(d) for d in FST_D)], float) elif match := TAG_RE.search(line): - curr[match.group('tag')].append([*to_type(get_numbers(line), float)]) + curr[match.group("tag")].append([*to_type(get_numbers(line), float)]) return steps diff --git a/castep_outputs/parsers/parse_fmt_files.py b/castep_outputs/parsers/parse_fmt_files.py index d6ffecf..475d7d6 100644 --- a/castep_outputs/parsers/parse_fmt_files.py +++ b/castep_outputs/parsers/parse_fmt_files.py @@ -14,19 +14,19 @@ def parse_elf_fmt_file(elf_file: TextIO) -> dict[str, list[int | float]]: """ Parse castep .elf_fmt files """ - return parse_kpt_info(elf_file, ('chi_alpha', 'chi_beta')) + return parse_kpt_info(elf_file, ("chi_alpha", "chi_beta")) def parse_chdiff_fmt_file(chdiff_file: TextIO) -> dict[str, list[int | float]]: """ Parse castep .chdiff_fmt files """ - return parse_kpt_info(chdiff_file, 'chdiff') + return parse_kpt_info(chdiff_file, "chdiff") def parse_pot_fmt_file(pot_file: TextIO) -> dict[str, list[int | float]]: """ Parse castep .pot_fmt files """ - return parse_kpt_info(pot_file, 'pot') + return parse_kpt_info(pot_file, "pot") def parse_den_fmt_file(den_file: TextIO) -> dict[str, list[int | float]]: """ Parse castep .den_fmt files """ - return parse_kpt_info(den_file, 'density') + return parse_kpt_info(den_file, "density") diff --git a/castep_outputs/parsers/parse_utilities.py b/castep_outputs/parsers/parse_utilities.py index ece7591..6516a81 100644 --- a/castep_outputs/parsers/parse_utilities.py +++ b/castep_outputs/parsers/parse_utilities.py @@ -26,7 +26,7 @@ def parse_regular_header(block: Block, _, _, *key, val = line.split() data[" ".join(key)] = int(float(val)) elif "Unit cell vectors" in line: - data['unit_cell'] = [to_type(next(block).split(), float) + data["unit_cell"] = [to_type(next(block).split(), float) for _ in range(3)] elif match := REs.ATDAT3VEC.search(line): @@ -39,12 +39,12 @@ def parse_regular_header(block: Block, elif match := re.search(f"({'|'.join(extra_opts)})", line): data[match.group(0)] = to_type(get_numbers(line), float) - fix_data_types(coords, {'index': int, - 'u': float, - 'v': float, - 'w': float, - 'mass': float}) - data['coords'] = coords + fix_data_types(coords, {"index": int, + "u": float, + "v": float, + "w": float, + "mass": float}) + data["coords"] = coords return data @@ -63,11 +63,11 @@ def parse_kpt_info(inp: TextIO, prop: str | Sequence[str]) -> dict[str, list[int *qpt, val = line.split() qpt = to_type(qpt, int) val = to_type(val, float) - stack_dict(qdata, {'q': qpt, prop: val}) + stack_dict(qdata, {"q": qpt, prop: val}) elif isinstance(prop, Sequence): words = line.split() qpt = to_type(words[0:3], int) val = to_type(words[3:], float) - stack_dict(qdata, {'q': qpt, **dict(zip(prop, val))}) + stack_dict(qdata, {"q": qpt, **dict(zip(prop, val))}) return qdata diff --git a/castep_outputs/parsers/phonon_dos_file_parser.py b/castep_outputs/parsers/phonon_dos_file_parser.py index b3088b4..7f8c2a7 100644 --- a/castep_outputs/parsers/phonon_dos_file_parser.py +++ b/castep_outputs/parsers/phonon_dos_file_parser.py @@ -32,17 +32,17 @@ def parse_phonon_dos_file(phonon_dos_file: TextIO) -> dict[str, Any]: qdata = defaultdict(list) def fix(qdat): - fix_data_types(qdat, {'qpt': float, - 'pth': float, - 'n': int, - 'f': float, - 'Grad_qf': float}) + fix_data_types(qdat, {"qpt": float, + "pth": float, + "n": int, + "f": float, + "Grad_qf": float}) for line in block: if match := REs.PHONON_PHONON_RE.match(line): if qdata: fix(qdata) - phonon_dos_info['gradients'].append(qdata) + phonon_dos_info["gradients"].append(qdata) qdata = defaultdict(list) @@ -54,7 +54,7 @@ def fix(qdat): if qdata: fix(qdata) - phonon_dos_info['gradients'].append(qdata) + phonon_dos_info["gradients"].append(qdata) elif block := Block.from_re(line, phonon_dos_file, "BEGIN DOS", "END DOS"): @@ -63,7 +63,7 @@ def fix(qdat): dos = defaultdict(list) # First chunk is " BEGIN DOS Freq (cm-1) g(f)", thus need the 5th on species = block[0].split()[5:] - headers = ('freq', 'g', *species) + headers = ("freq", "g", *species) rows = re.compile(labelled_floats(headers)) block.remove_bounds(1, 2) @@ -74,6 +74,6 @@ def fix(qdat): if dos: fix_data_types(dos, {key: float for key in headers}) - phonon_dos_info['dos'].append(dos) + phonon_dos_info["dos"].append(dos) return phonon_dos_info diff --git a/castep_outputs/parsers/phonon_file_parser.py b/castep_outputs/parsers/phonon_file_parser.py index 97fa930..c03f367 100755 --- a/castep_outputs/parsers/phonon_file_parser.py +++ b/castep_outputs/parsers/phonon_file_parser.py @@ -35,16 +35,16 @@ def parse_phonon_file(phonon_file: TextIO) -> dict[str, Any]: for line in block: if "q-pt" in line: _, _, posx, posy, posz, *weight = line.split() - qdata = {'pos': [posx, posy, posz], 'weight': weight} - fix_data_types(qdata, {'pos': float, - 'weight': float}) - phonon_info["qpt_pos"].append(qdata['pos']) + qdata = {"pos": [posx, posy, posz], "weight": weight} + fix_data_types(qdata, {"pos": float, + "weight": float}) + phonon_info["qpt_pos"].append(qdata["pos"]) elif "Eigenvectors" not in line: _, e_val, *_ = line.split() - qdata = {'eval': e_val} - fix_data_types(qdata, {'eval': float}) - evals.append(qdata['eval']) + qdata = {"eval": e_val} + fix_data_types(qdata, {"eval": float}) + evals.append(qdata["eval"]) if len(evals) == phonon_info["branches"]: phonon_info["evals"].append(evals) evals = [] @@ -56,12 +56,12 @@ def parse_phonon_file(phonon_file: TextIO) -> dict[str, Any]: if "Mode" not in line: _, _, *vectors = line.split() - qdata = {'evec': vectors} - fix_data_types(qdata, {'evec': float}) - qdata['evec'] = [complex(qdata['evec'][i], - qdata['evec'][i+1]) + qdata = {"evec": vectors} + fix_data_types(qdata, {"evec": float}) + qdata["evec"] = [complex(qdata["evec"][i], + qdata["evec"][i+1]) for i in range(0, len(vectors), 2)] - evecs.append(qdata['evec']) + evecs.append(qdata["evec"]) if len(evecs) == phonon_info["branches"]*phonon_info["ions"]: phonon_info["evecs"].append(evecs) diff --git a/castep_outputs/parsers/ts_file_parser.py b/castep_outputs/parsers/ts_file_parser.py index 57a3a63..4404d34 100644 --- a/castep_outputs/parsers/ts_file_parser.py +++ b/castep_outputs/parsers/ts_file_parser.py @@ -26,7 +26,7 @@ def parse_ts_file(ts_file: TextIO) -> dict[str, Any]: elif block := Block.from_re(line, ts_file, "(REA|PRO|TST)", r"^\s*$", eof_possible=True): curr = defaultdict(list) match = re.match(r"\s*(?PREA|PRO|TST)\s*\d+\s*" + - labelled_floats(('reaction_coordinate',)), line) + labelled_floats(("reaction_coordinate",)), line) key = TS_TYPES[match["type"]] curr["reaction_coordinate"] = to_type(match["reaction_coordinate"], float) @@ -35,12 +35,12 @@ def parse_ts_file(ts_file: TextIO) -> dict[str, Any]: ion = atreg_to_index(match) if ion not in curr: curr[ion] = {} - curr[ion][match.group('tag')] = to_type([*(match.group(d) + curr[ion][match.group("tag")] = to_type([*(match.group(d) for d in FST_D)], float) add_aliases(curr[ion], TAG_ALIASES) elif match := TAG_RE.search(blk_line): - curr[match.group('tag')].append([*to_type(get_numbers(blk_line), float)]) + curr[match.group("tag")].append([*to_type(get_numbers(blk_line), float)]) add_aliases(curr, TAG_ALIASES) accum[key].append(curr) diff --git a/castep_outputs/utilities/castep_res.py b/castep_outputs/utilities/castep_res.py index 028cdf6..72cf172 100644 --- a/castep_outputs/utilities/castep_res.py +++ b/castep_outputs/utilities/castep_res.py @@ -187,14 +187,14 @@ def get_atom_parts(spec: str) -> dict[str, str]: # Pair pot PAIR_POT_RES = { - 'two_body_one_spec': re.compile( + "two_body_one_spec": re.compile( rf"^(?P\w+)?\s*\*\s*(?P{ATOM_NAME_RE})\s*\*\s*$", ), - 'two_body_spec': re.compile( + "two_body_spec": re.compile( rf"(?P{ATOM_NAME_RE})\s*-\s*" rf"(?P{ATOM_NAME_RE})", ), - 'two_body_val': re.compile( + "two_body_val": re.compile( rf""" (?P\w+)?\s*\*\s* (?P