|
10 | 10 | import numpy as np
|
11 | 11 | from defusedxml import ElementTree as ET
|
12 | 12 |
|
| 13 | +from ..._fiff.constants import FIFF |
13 | 14 | from ..._fiff.meas_info import create_info
|
14 | 15 | from ...utils import _check_fname, fill_doc, logger, verbose, warn
|
15 | 16 | from ..base import BaseRaw
|
@@ -53,7 +54,7 @@ def _parse_otb_plus_metadata(metadata, extras_metadata):
|
53 | 54 | n_chan = int(metadata.attrib["DeviceTotalChannels"])
|
54 | 55 | bit_depth = int(metadata.attrib["ad_bits"])
|
55 | 56 | device_name = metadata.attrib["Name"]
|
56 |
| - adc_range = 3.3 # TODO is this V or mV ?? |
| 57 | + adc_range = 0.0033 # 3.3 mV (TODO VERIFY) |
57 | 58 | # containers
|
58 | 59 | gains = np.full(n_chan, np.nan)
|
59 | 60 | ch_names = list()
|
@@ -93,11 +94,19 @@ def _parse_otb_plus_metadata(metadata, extras_metadata):
|
93 | 94 | gain_ix = ix + ch_offset
|
94 | 95 | gains[gain_ix] = float(ch.get("Gain")) * adapter_gain
|
95 | 96 | # TODO verify ch_type for quats, buffer channel, and ramp channel
|
96 |
| - ch_types.append( |
97 |
| - "misc" |
98 |
| - if ch_id in _NON_DATA_CHS or ch_id.lower().startswith("aux") |
99 |
| - else "emg" |
100 |
| - ) |
| 97 | + # ramp and controls channels definitely "MISC" |
| 98 | + # quats should maybe be FIFF.FIFFV_QUAT_{N} (N from 0-6), but need to verify |
| 99 | + # what quats should be, as there are only 4 quat channels. The FIFF quats: |
| 100 | + # 0: obsolete |
| 101 | + # 1-3: rotations |
| 102 | + # 4-6: translations |
| 103 | + if ch_id == "Quaternions": |
| 104 | + ch_type = FIFF.FIFFV_QUAT_0 # TODO verify |
| 105 | + elif ch_id in _NON_DATA_CHS or ch_id.lower().startswith("aux"): |
| 106 | + ch_type = "misc" |
| 107 | + else: |
| 108 | + ch_type = "emg" |
| 109 | + ch_types.append(ch_type) |
101 | 110 | # parse subject info
|
102 | 111 | subject_info = _parse_patient_xml(extras_metadata)
|
103 | 112 |
|
@@ -248,7 +257,13 @@ def __init__(self, fname, *, verbose=None):
|
248 | 257 | info["lowpass"] = lowpass
|
249 | 258 | for ix, _ch in enumerate(info["chs"]):
|
250 | 259 | cal = 1 / 2**bit_depth / gains[ix]
|
251 |
| - _ch.update(cal=cal, range=adc_range) |
| 260 | + # TODO need different range for Quaternions? |
| 261 | + _range = ( |
| 262 | + adc_range |
| 263 | + if _ch["kind"] in (FIFF.FIFFV_EMG_CH, FIFF.FIFFV_EEG_CH) |
| 264 | + else 1.0 |
| 265 | + ) |
| 266 | + _ch.update(cal=cal, range=_range) |
252 | 267 | if meas_date is not None:
|
253 | 268 | info["meas_date"] = datetime.fromisoformat(meas_date.text).astimezone(
|
254 | 269 | timezone.utc
|
@@ -308,13 +323,7 @@ def _preload_data(self, preload):
|
308 | 323 | else:
|
309 | 324 | _data = np.concatenate(_data, axis=0)
|
310 | 325 |
|
311 |
| - # TODO without this fudge factor, the scale of the signals seems way too high |
312 |
| - # (sample data channels show a dynamic range of 0.2 - 3.3 V) |
313 |
| - # the puzzling thing is that in the MATLAB code the fudge is 1e3 (not 1e-3) ?!? |
314 |
| - fudge_factor = 1e-3 |
315 |
| - cals = np.array( |
316 |
| - [_ch["cal"] * _ch["range"] * fudge_factor for _ch in self.info["chs"]] |
317 |
| - ) |
| 326 | + cals = np.array([_ch["cal"] * _ch["range"] for _ch in self.info["chs"]]) |
318 | 327 | self._data = _data * cals[:, np.newaxis]
|
319 | 328 |
|
320 | 329 |
|
|
0 commit comments