Spaces:
Sleeping
Sleeping
Commit
·
7129427
1
Parent(s):
441b340
init
Browse files- channel_mapping.py +173 -0
- template_chanlocs.loc +30 -0
channel_mapping.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import utils
|
| 2 |
+
import os
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
import mne
|
| 6 |
+
from mne.channels import read_custom_montage
|
| 7 |
+
|
| 8 |
+
def reorder_data(filename, old_idx):
|
| 9 |
+
filepath = os.path.dirname(str(filename))
|
| 10 |
+
old_data = utils.read_train_data(filename)
|
| 11 |
+
new_data = np.zeros((30, old_data.shape[1]))
|
| 12 |
+
#print('old = ', old_data.shape)
|
| 13 |
+
|
| 14 |
+
for j in range(30):
|
| 15 |
+
new_data[j, :] = old_data[old_idx[j]-1, :]
|
| 16 |
+
|
| 17 |
+
#print('i = ', i+1, ', ', new_data.shape)
|
| 18 |
+
utils.save_data(new_data, filepath+'/mapped.csv')
|
| 19 |
+
return
|
| 20 |
+
|
| 21 |
+
def mapping(input_file, loc_file, fill_mode):
|
| 22 |
+
template_montage = read_custom_montage("./template_chanlocs.loc")
|
| 23 |
+
input_montage = read_custom_montage(loc_file)
|
| 24 |
+
#template_montage.plot()
|
| 25 |
+
#input_montage.plot()
|
| 26 |
+
|
| 27 |
+
input_labels_dict = {}
|
| 28 |
+
for i in range(30):
|
| 29 |
+
template_montage.rename_channels({template_montage.ch_names[i]:str.upper(template_montage.ch_names[i])}) # 統一大寫
|
| 30 |
+
|
| 31 |
+
for i in range(len(input_montage.ch_names)):
|
| 32 |
+
input_montage.rename_channels({input_montage.ch_names[i]:str.upper(input_montage.ch_names[i])}) # 統一大寫
|
| 33 |
+
input_labels_dict[input_montage.ch_names[i]] = i
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
new_idx = [-1]*30
|
| 37 |
+
new_idx_name = ['']*30 # tmp
|
| 38 |
+
input_used = [0]*len(input_montage.ch_names)
|
| 39 |
+
finish_flag = 1
|
| 40 |
+
|
| 41 |
+
alias = {'T3':'T7', 'T4':'T8', 'T5':'P7', 'T6':'P8'} # CP7,FT7 ?
|
| 42 |
+
|
| 43 |
+
# correct place
|
| 44 |
+
for i in range(30):
|
| 45 |
+
channel_name = template_montage.ch_names[i]
|
| 46 |
+
|
| 47 |
+
if channel_name in input_labels_dict:
|
| 48 |
+
new_idx[i] = input_labels_dict[channel_name]
|
| 49 |
+
new_idx_name[i] = channel_name # tmp
|
| 50 |
+
|
| 51 |
+
input_used[new_idx[i]] = 1
|
| 52 |
+
|
| 53 |
+
elif channel_name in alias:
|
| 54 |
+
template_montage.rename_channels({channel_name:alias[channel_name]})
|
| 55 |
+
channel_name = template_montage.ch_names[i]
|
| 56 |
+
new_idx[i] = input_labels_dict[channel_name]
|
| 57 |
+
new_idx_name[i] = channel_name # tmp
|
| 58 |
+
|
| 59 |
+
input_used[new_idx[i]] = 1
|
| 60 |
+
else:
|
| 61 |
+
finish_flag = 0
|
| 62 |
+
|
| 63 |
+
if finish_flag == 1:
|
| 64 |
+
print('Finish at stage 1,2 !')
|
| 65 |
+
reorder_data(input_file, new_idx) # & save data to mapped.csv
|
| 66 |
+
return
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
# store channel positions in 2-d array
|
| 71 |
+
template_pos = []
|
| 72 |
+
template_pos_idx = []
|
| 73 |
+
|
| 74 |
+
temporal_channels = []
|
| 75 |
+
temporal_row_prefix = ['FC','C','CP','P']
|
| 76 |
+
|
| 77 |
+
cnt = 0
|
| 78 |
+
for i in range(7):
|
| 79 |
+
tmp = []
|
| 80 |
+
for j in range(5):
|
| 81 |
+
if [i,j] in [[0,0],[0,2],[0,4],[6,0],[6,4]]:
|
| 82 |
+
tmp.append('')
|
| 83 |
+
else:
|
| 84 |
+
tmp.append(template_montage.ch_names[cnt])
|
| 85 |
+
template_pos_idx.append([i,j])
|
| 86 |
+
|
| 87 |
+
if i>1 and j in [0,4]:
|
| 88 |
+
temporal_channels.append(template_montage.ch_names[cnt])
|
| 89 |
+
cnt += 1
|
| 90 |
+
template_pos.append(tmp)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
# CZ
|
| 95 |
+
template_CZ_idx = 14
|
| 96 |
+
if new_idx[template_CZ_idx] == -1:
|
| 97 |
+
min_dist = 1e5
|
| 98 |
+
nearest_channel = 'CZ'
|
| 99 |
+
for channel in input_montage.ch_names:
|
| 100 |
+
cur_x, cur_y, cur_z = input_montage.get_positions()['ch_pos'][channel]
|
| 101 |
+
if cur_x**2+cur_y**2 < min_dist and channel != 'CZ':
|
| 102 |
+
nearest_channel = channel
|
| 103 |
+
min_dist = cur_x**2+cur_y**2
|
| 104 |
+
input_labels_dict['CZ'] = input_labels_dict[nearest_channel]
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
finish_flag = 1
|
| 109 |
+
|
| 110 |
+
if fill_mode == "zero":
|
| 111 |
+
z_row_idx = len(input_montage.ch_names)
|
| 112 |
+
|
| 113 |
+
for i in range(30):
|
| 114 |
+
if new_idx[i] != -1:
|
| 115 |
+
continue
|
| 116 |
+
|
| 117 |
+
channel_name = template_montage.ch_names[i]
|
| 118 |
+
channel_prefix = channel_name[:len(channel_name)-1]
|
| 119 |
+
channel_suffix = -1 if channel_name[-1]=='Z' else int(channel_name[-1])
|
| 120 |
+
|
| 121 |
+
# current target channel is in the middle
|
| 122 |
+
if channel_suffix == -1:
|
| 123 |
+
|
| 124 |
+
if fill_mode == "zero":
|
| 125 |
+
new_idx[i] = z_row_idx
|
| 126 |
+
|
| 127 |
+
elif fill_mode == "adjacent":
|
| 128 |
+
|
| 129 |
+
if channel_prefix+str(1) in input_labels_dict: # ex: FCZ<-FC1
|
| 130 |
+
new_idx[i] = input_labels_dict[channel_prefix+str(1)]
|
| 131 |
+
new_idx_name[i] = channel_prefix+str(1) # tmp
|
| 132 |
+
elif (channel_name in ['FCZ','CPZ']): # and ('CZ' in input_labels_dict): # ex: FCZ<-CZ
|
| 133 |
+
new_idx[i] = input_labels_dict['CZ']
|
| 134 |
+
new_idx_name[i] = 'CZ' # tmp
|
| 135 |
+
elif channel_prefix+str(3) in input_labels_dict: # ex: FCZ<-FC3
|
| 136 |
+
new_idx[i] = input_labels_dict[channel_prefix+str(3)]
|
| 137 |
+
new_idx_name[i] = channel_prefix+str(3) # tmp
|
| 138 |
+
else:
|
| 139 |
+
new_idx[i] = input_labels_dict['CZ']
|
| 140 |
+
new_idx_name[i] = 'CZ' # tmp
|
| 141 |
+
|
| 142 |
+
# current target channel is in the left/right region
|
| 143 |
+
else:
|
| 144 |
+
try:
|
| 145 |
+
# if the current target channel is a temporal channel
|
| 146 |
+
potential_neighbor = temporal_row_prefix[temporal_channels.index(channel_name)//2]+str(5 if channel_suffix%2==1 else 6) # ex: FT7<-FC5
|
| 147 |
+
except:
|
| 148 |
+
potential_neighbor = channel_name[:len(channel_name)-1]+str(channel_suffix-2) # ex: FC3<-FC1, FC4<-FC2
|
| 149 |
+
|
| 150 |
+
if (potential_neighbor in input_labels_dict) and (input_used[input_labels_dict[potential_neighbor]]==0):
|
| 151 |
+
new_idx[i] = input_labels_dict[potential_neighbor]
|
| 152 |
+
new_idx_name[i] = potential_neighbor # tmp
|
| 153 |
+
|
| 154 |
+
input_used[new_idx[i]] = 1
|
| 155 |
+
else:
|
| 156 |
+
if fill_mode == "zero":
|
| 157 |
+
new_idx[i] = z_row_idx
|
| 158 |
+
elif fill_mode == "adjacent": # 先這樣暫時這樣...QQ
|
| 159 |
+
mid_channel = template_pos[template_pos_idx[i][0]][2]
|
| 160 |
+
mid_channel_idx = template_montage.ch_names.index(mid_channel)
|
| 161 |
+
new_idx[i] = new_idx[mid_channel_idx]
|
| 162 |
+
new_idx_name[i] = mid_channel # tmp
|
| 163 |
+
|
| 164 |
+
#finish_flag = 0
|
| 165 |
+
|
| 166 |
+
#if finish_flag == 1:
|
| 167 |
+
# print('Finish at stage 3,4 !')
|
| 168 |
+
# reorder_data(input_file, new_idx) # & save data to mapped.csv
|
| 169 |
+
# return
|
| 170 |
+
#else:
|
| 171 |
+
# print('Error: the channel mapping process has failed!')
|
| 172 |
+
reorder_data(input_file, new_idx)
|
| 173 |
+
|
template_chanlocs.loc
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
1 -19.33 0.52497 FP1
|
| 2 |
+
2 19.385 0.52499 FP2
|
| 3 |
+
3 -58.847 0.54399 F7
|
| 4 |
+
4 -43.411 0.33339 F3
|
| 5 |
+
5 0.30571 0.22978 FZ
|
| 6 |
+
6 43.668 0.34149 F4
|
| 7 |
+
7 58.694 0.54439 F8
|
| 8 |
+
8 -80.084 0.54296 FT7
|
| 9 |
+
9 -69.321 0.27328 FC3
|
| 10 |
+
10 0.7867 0.095376 FCZ
|
| 11 |
+
11 69.152 0.27863 FC4
|
| 12 |
+
12 79.329 0.54305 FT8
|
| 13 |
+
13 -100.78 0.53459 T3
|
| 14 |
+
14 -100.09 0.25493 C3
|
| 15 |
+
15 177.5 0.029055 CZ
|
| 16 |
+
16 99.225 0.26068 C4
|
| 17 |
+
17 100.01 0.53482 T4
|
| 18 |
+
18 -118.48 0.52323 TP7
|
| 19 |
+
19 -126.49 0.27946 CP3
|
| 20 |
+
20 179.53 0.14139 CPZ
|
| 21 |
+
21 125 0.28397 CP4
|
| 22 |
+
22 118.03 0.52338 TP8
|
| 23 |
+
23 -135.4 0.50767 T5
|
| 24 |
+
24 -146.07 0.33054 P3
|
| 25 |
+
25 179.77 0.24709 PZ
|
| 26 |
+
26 144.68 0.33093 P4
|
| 27 |
+
27 135 0.50782 T6
|
| 28 |
+
28 -165.34 0.47584 O1
|
| 29 |
+
29 179.95 0.45961 OZ
|
| 30 |
+
30 165.1 0.47591 O2
|