-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathUtils_Bashivan.py
executable file
·124 lines (109 loc) · 5.13 KB
/
Utils_Bashivan.py
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
'''
Created by Pouya bashivan
This code has been created by p. bashivan source : https://github.com/pbashivan/EEGLearn
'''
__author__ = 'Pouya Bashivan'
import numpy as np
np.random.seed(123)
import scipy.io
from scipy.interpolate import griddata
from sklearn.preprocessing import scale
import math as m
from sklearn.decomposition import PCA
def azim_proj(pos):
"""
Computes the Azimuthal Equidistant Projection of input point in 3D Cartesian Coordinates.
Imagine a plane being placed against (tangent to) a globe. If
a light source inside the globe projects the graticule onto
the plane the result would be a planar, or azimuthal, map
projection.
:param pos: position in 3D Cartesian coordinates
:return: projected coordinates using Azimuthal Equidistant Projection
"""
[r, elev, az] = cart2sph(pos[0], pos[1], pos[2])
return pol2cart(az, m.pi / 2 - elev)
def cart2sph(x, y, z):
"""
Transform Cartesian coordinates to spherical
:param x: X coordinate
:param y: Y coordinate
:param z: Z coordinate
:return: radius, elevation, azimuth
"""
x2_y2 = x**2 + y**2
r = m.sqrt(x2_y2 + z**2) # r
elev = m.atan2(z, m.sqrt(x2_y2)) # Elevation
az = m.atan2(y, x) # Azimuth
return r, elev, az
def pol2cart(theta, rho):
"""
Transform polar coordinates to Cartesian
:param theta: angle value
:param rho: radius value
:return: X, Y
"""
return rho * m.cos(theta), rho * m.sin(theta)
def gen_images(locs, features, n_gridpoints, normalize=True,
augment=False, pca=False, std_mult=0.1, n_components=2, edgeless=False):
"""
Generates EEG images given electrode locations in 2D space and multiple feature values for each electrode
:param locs: An array with shape [n_electrodes, 2] containing X, Y
coordinates for each electrode.
:param features: Feature matrix as [n_samples, n_features]
Features are as columns.
Features corresponding to each frequency band are concatenated.
(alpha1, alpha2, ..., beta1, beta2,...)
:param n_gridpoints: Number of pixels in the output images
:param normalize: Flag for whether to normalize each band over all samples
:param augment: Flag for generating augmented images
:param pca: Flag for PCA based data augmentation
:param std_mult Multiplier for std of added noise
:param n_components: Number of components in PCA to retain for augmentation
:param edgeless: If True generates edgeless images by adding artificial channels
at four corners of the image with value = 0 (default=False).
:return: Tensor of size [samples, colors, W, H] containing generated
images.
"""
feat_array_temp = []
nElectrodes = locs.shape[0] # Number of electrodes
# Test whether the feature vector length is divisible by number of electrodes
assert features.shape[1] % nElectrodes == 0
n_colors = int(features.shape[1] / nElectrodes)
for c in range(n_colors):
feat_array_temp.append(features[:, c * nElectrodes : nElectrodes * (c+1)])
if augment:
if pca:
for c in range(n_colors):
feat_array_temp[c] = augment_EEG(feat_array_temp[c], std_mult, pca=True, n_components=n_components)
else:
for c in range(n_colors):
feat_array_temp[c] = augment_EEG(feat_array_temp[c], std_mult, pca=False, n_components=n_components)
n_samples = features.shape[0]
# Interpolate the values
grid_x, grid_y = np.mgrid[
min(locs[:, 0]):max(locs[:, 0]):n_gridpoints*1j,
min(locs[:, 1]):max(locs[:, 1]):n_gridpoints*1j
]
temp_interp = []
for c in range(n_colors):
temp_interp.append(np.zeros([n_samples, n_gridpoints, n_gridpoints]))
# Generate edgeless images
if edgeless:
min_x, min_y = np.min(locs, axis=0)
max_x, max_y = np.max(locs, axis=0)
locs = np.append(locs, np.array([[min_x, min_y], [min_x, max_y], [max_x, min_y], [max_x, max_y]]), axis=0)
for c in range(n_colors):
feat_array_temp[c] = np.append(feat_array_temp[c], np.zeros((n_samples, 4)), axis=1)
# Interpolating
for i in range(n_samples):
for c in range(n_colors):
temp_interp[c][i, :, :] = griddata(locs, feat_array_temp[c][i, :], (grid_x, grid_y),
method='cubic', fill_value=np.nan)
print('Interpolating {0}/{1}\r'.format(i + 1, n_samples), end='\r')
# Normalizing
for c in range(n_colors):
if normalize:
temp_interp[c][~np.isnan(temp_interp[c])] = \
scale(temp_interp[c][~np.isnan(temp_interp[c])])
temp_interp[c] = np.nan_to_num(temp_interp[c])
return np.swapaxes(np.asarray(temp_interp), 0, 1) # swap axes to have [samples, colors, W, H]