File: hc.py

package info (click to toggle)
python-mne 1.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 131,492 kB
  • sloc: python: 213,302; javascript: 12,910; sh: 447; makefile: 144
file content (89 lines) | stat: -rw-r--r-- 2,527 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""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)