Spaces:
Running
Running
| """Read .hc files.""" | |
| # Authors: The MNE-Python contributors. | |
| # License: BSD-3-Clause | |
| # Copyright the MNE-Python contributors. | |
| import numpy as np | |
| from ..._fiff.constants import FIFF | |
| from ...utils import logger | |
| from .constants import CTF | |
| from .res4 import _make_ctf_name | |
| _kind_dict = { | |
| "nasion": CTF.CTFV_COIL_NAS, | |
| "left ear": CTF.CTFV_COIL_LPA, | |
| "right ear": CTF.CTFV_COIL_RPA, | |
| "spare": CTF.CTFV_COIL_SPARE, | |
| } | |
| _coord_dict = { | |
| "relative to dewar": FIFF.FIFFV_MNE_COORD_CTF_DEVICE, | |
| "relative to head": FIFF.FIFFV_MNE_COORD_CTF_HEAD, | |
| } | |
| def _read_one_coil_point(fid): | |
| """Read coil coordinate information from the hc file.""" | |
| # Descriptor | |
| one = "#" | |
| while len(one) > 0 and one[0] == "#": | |
| one = fid.readline() | |
| if len(one) == 0: | |
| return None | |
| one = one.strip().decode("utf-8") | |
| if "Unable" in one: | |
| raise RuntimeError("HPI information not available") | |
| # Hopefully this is an unambiguous interpretation | |
| p = dict() | |
| p["valid"] = "measured" in one | |
| for key, val in _coord_dict.items(): | |
| if key in one: | |
| p["coord_frame"] = val | |
| break | |
| else: | |
| p["coord_frame"] = -1 | |
| for key, val in _kind_dict.items(): | |
| if key in one: | |
| p["kind"] = val | |
| break | |
| else: | |
| p["kind"] = -1 | |
| # Three coordinates | |
| p["r"] = np.empty(3) | |
| for ii, coord in enumerate("xyz"): | |
| sp = fid.readline().decode("utf-8").strip() | |
| if len(sp) == 0: # blank line | |
| continue | |
| sp = sp.split(" ") | |
| if len(sp) != 3 or sp[0] != coord or sp[1] != "=": | |
| raise RuntimeError(f"Bad line: {one}") | |
| # We do not deal with centimeters | |
| p["r"][ii] = float(sp[2]) / 100.0 | |
| return p | |
| def _read_hc(directory): | |
| """Read the hc file to get the HPI info and to prepare for coord trans.""" | |
| fname, found = _make_ctf_name(directory, "hc", raise_error=False) | |
| if not found: | |
| logger.info(" hc data not present") | |
| return None | |
| s = list() | |
| with open(fname, "rb") as fid: | |
| while True: | |
| p = _read_one_coil_point(fid) | |
| if p is None: | |
| # First point bad indicates that the file is empty | |
| if len(s) == 0: | |
| logger.info("hc file empty, no data present") | |
| return None | |
| # Returns None if at EOF | |
| logger.info(" hc data read.") | |
| return s | |
| if p["valid"]: | |
| s.append(p) | |