|
| 1 | +import os |
| 2 | +import numpy as np |
| 3 | +from torch.utils import data |
| 4 | +from scipy.io import loadmat |
| 5 | +from ..utils.units import Hz |
| 6 | + |
| 7 | + |
| 8 | +class ECoGJoystickTracking(data.Dataset): |
| 9 | + """Helper class to read the ECoG Joystick Tracking dataset from |
| 10 | + Schalk, G., J. Kubanek, K. J. Miller, N. R. Anderson, E. C. Leuthardt, J. G. Ojemann, D. Limbrick, D. Moran, L. A. Gerhardt, and J. R. Wolpaw. "Decoding two-dimensional movement trajectories using electrocorticographic signals in humans." Journal of neural engineering 4, no. 3 (2007): 264 |
| 11 | +
|
| 12 | + Ethics statement: All patients participated in a purely voluntary manner, after providing informed written consent, under experimental protocols approved by the Institutional Review Board of the University of Washington (#12193). All patient data was anonymized according to IRB protocol, in accordance with HIPAA mandate. It was made available through the library described in “A Library of Human Electrocorticographic Data and Analyses” by Kai Miller [Reference], freely available at https://searchworks.stanford.edu/view/zk881ps0522 |
| 13 | + """ |
| 14 | + |
| 15 | + def __init__(self, path, transforms=None, users=["fp", "gf", "rh", "rr"]): |
| 16 | + assert os.path.exists(path), f"Data not found at '{path}'" |
| 17 | + self.path = path |
| 18 | + self.transforms = transforms |
| 19 | + self.fs = 1000 * Hz # Sampling frequency |
| 20 | + self.users = users |
| 21 | + |
| 22 | + @property |
| 23 | + def nsfilt(self): |
| 24 | + # amplitude roll-off function used for filtering |
| 25 | + return loadmat(os.path.join(self.path, "ns_1k_1_300_filt.mat"))["nsfilt"] |
| 26 | + |
| 27 | + def _loadmat(self, index): |
| 28 | + return loadmat(os.path.join(self.path, "data", f"{self.users[index]}_joystick.mat")) |
| 29 | + |
| 30 | + def electrode_positions(self, index): |
| 31 | + # Talairach coordinate systems for the 60 electrodes |
| 32 | + return self._loadmat(index)["electrodes"] |
| 33 | + |
| 34 | + def __len__(self): |
| 35 | + return len(self.users) |
| 36 | + |
| 37 | + def __getitem__(self, index): |
| 38 | + """Return electrode data (n_electrode x time) and labels (4 x time), with labels = (x, y, target_x, target_y)""" |
| 39 | + mat = self._loadmat(index) |
| 40 | + data = mat["data"] if self.transforms is None else self.transforms(mat["data"]) |
| 41 | + return data.T, np.stack((mat["CursorPosX"], mat["CursorPosY"], mat["TargetPosX"], mat["TargetPosY"])).squeeze() |
0 commit comments