audrey06100 commited on
Commit
7a54f74
·
1 Parent(s): 29201f7

update css

Browse files
Files changed (2) hide show
  1. app.py +116 -76
  2. channel_mapping.py +40 -43
app.py CHANGED
@@ -34,7 +34,7 @@ If your data doesn't contain all of the mentioned channels, there are 3 imputati
34
  Firstly, we will attempt to find neighboring channel to use as alternative. For instance, if the required channel is **FC3** but you only have **FC1**, we will use it as a replacement for **FC3**.
35
  Then, depending on the **Imputation** way you chose, we will:
36
  - **zero**: fill the missing channels with zeros.
37
- - **adjacent**: fill the missing channels using neighboring channels which are located closer to the center. For example, if the required channel is **F3** but you only have **F7, FZ**, then we will choose **FZ** as the imputing value for **F3**.
38
  >Note: The imputed channels **need to be removed** after the data being reconstructed.
39
 
40
  ### Mapping result
@@ -63,6 +63,39 @@ icunet = """
63
  Electroencephalography (EEG) signals are often contaminated with artifacts. It is imperative to develop a practical and reliable artifact removal method to prevent the misinterpretation of neural signals and the underperformance of brain–computer interfaces. Based on the U-Net architecture, we developed a new artifact removal model, IC-U-Net, for removing pervasive EEG artifacts and reconstructing brain signals. IC-U-Net was trained using mixtures of brain and non-brain components decomposed by independent component analysis. It uses an ensemble of loss functions to model complex signal fluctuations in EEG recordings. The effectiveness of the proposed method in recovering brain activities and removing various artifacts (e.g., eye blinks/movements, muscle activities, and line/channel noise) was demonstrated in a simulation study and four real-world EEG experiments. IC-U-Net can reconstruct a multi-channel EEG signal and is applicable to most artifact types, offering a promising end-to-end solution for automatically removing artifacts from EEG recordings. It also meets the increasing need to image natural brain dynamics in a mobile setting.
64
  """
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  with gr.Blocks() as demo:
68
 
@@ -71,8 +104,7 @@ with gr.Blocks() as demo:
71
  with gr.Row():
72
  gr.Markdown(
73
  """
74
- # Introduction
75
- (...)
76
  """
77
  )
78
  with gr.Row():
@@ -100,29 +132,17 @@ with gr.Blocks() as demo:
100
  """,
101
  visible=False
102
  )
103
- #chk_md = gr.Markdown(
104
- # """
105
- # select...
106
- # """,
107
- # visible=False
108
- # )
109
  with gr.Row():
110
  tpl_montage = gr.Image("./template_montage.png", label="Template montage", visible=False)
111
  map_montage = gr.Image(label="Choosen channels", visible=False)
112
- in_montage = gr.Image(label="Input montage", visible=False)
113
- with gr.Accordion(visible=False) as accordion:
114
- with gr.Column():
115
- #chk_block = gr.HTML(chk_html)
116
- #in_montage = gr.Image(label="Input montage")
117
- chs_chkbox = gr.CheckboxGroup(elem_classes="chs-chkbox", label="")
118
- next_btn = gr.Button("Next", interactive=False)
119
  miss_txtbox = gr.Textbox(label="Missing channels", visible=False)
120
  tpl_loc_file = gr.File("./template_chanlocs.loc", show_label=False, visible=False)
121
- #test_file = gr.File(label="test")
122
  with gr.Column():
123
  gr.Markdown(
124
  """
125
- # 2.Decode Data(?)
126
  """
127
  )
128
  with gr.Row():
@@ -146,7 +166,7 @@ with gr.Blocks() as demo:
146
  with gr.Tab("QuickStart"):
147
  gr.Markdown(quickstart)
148
 
149
- #demo.load(js=chk_script)
150
 
151
  def reset_layout(raw_data):
152
  # establish temp folder
@@ -157,15 +177,16 @@ with gr.Blocks() as demo:
157
  utils.dataDelete(filepath+"/temp_data/")
158
  os.mkdir(filepath+"/temp_data/")
159
  #print(e)
160
-
161
- return {state_json : {"filepath" : filepath+"/temp_data/"},
162
- accordion : gr.Accordion(visible=False),
163
- chs_chkbox : gr.CheckboxGroup(choices=[], value=[], label=""), # choices, value ???
164
- next_btn : gr.Button("Next", interactive=False),
 
 
165
  run_btn : gr.Button(interactive=False),
166
  tpl_montage : gr.Image(visible=False),
167
- map_montage : gr.Image(value=None, visible=False), #tmp
168
- in_montage : gr.Image(value=None, visible=False),
169
  miss_txtbox : gr.Textbox(visible=False),
170
  res_md : gr.Markdown(visible=False),
171
  tpl_loc_file : gr.File(visible=False)}
@@ -181,7 +202,7 @@ with gr.Blocks() as demo:
181
  })
182
  #print("Missing channels:", state_obj["missingChannelsIndex"])
183
  return {state_json : state_obj,
184
- accordion : gr.Accordion(visible=True)}
185
  else:
186
  reorder_data(raw_data, channels_obj["newOrder"], fill_mode, state_obj)
187
 
@@ -202,23 +223,29 @@ with gr.Blocks() as demo:
202
  def show_montage(state_obj, raw_loc):
203
  filepath = state_obj["filepath"]
204
  raw_montage = read_custom_montage(raw_loc)
 
 
205
  for i in range(len(raw_montage.ch_names)):
206
  channel = raw_montage.ch_names[i]
207
  raw_montage.rename_channels({channel: str.upper(channel)})
208
 
209
  if state_obj["state"] == "initializing":
210
  filename = filepath+"raw_montage_"+str(random.randint(1,10000))+".png"
 
211
  raw_fig = raw_montage.plot()
212
- raw_fig.savefig(filename)
 
213
 
214
- return {tpl_montage : gr.Image(visible=True),
215
- in_montage : gr.Image(value=filename, visible=True),
216
- map_montage : gr.Image(visible=False)}
 
217
 
218
  elif state_obj["state"] == "finished":
219
  # didn't find any way to hide the dark points...
220
  # tmp
221
  filename = filepath+"mapped_montage_"+str(random.randint(1,10000))+".png"
 
222
 
223
  show_names= []
224
  for channel in state_obj["inputByName"]:
@@ -227,36 +254,37 @@ with gr.Blocks() as demo:
227
  continue
228
  show_names.append(channel)
229
  mapped_fig = raw_montage.plot(show_names=show_names)
230
- mapped_fig.savefig(filename)
 
231
 
232
- return {tpl_montage : gr.Image(visible=True),
233
- in_montage : gr.Image(visible=False),
234
- map_montage : gr.Image(value=filename, visible=True)} # value=,
235
 
236
  elif state_obj["state"] == "selecting":
237
- # need to update in_montage here
238
- return {in_montage : gr.Image()}
 
239
 
240
  def generate_chkbox(state_obj):
241
  if state_obj["state"] == "initializing":
242
  in_channels = [channel for channel in state_obj["inputByName"]]
243
  state_obj["state"] = "selecting"
244
- # and img....?
245
 
246
  first_idx = state_obj["missingChannelsIndex"][0]
247
  first_name = state_obj["templateByIndex"][first_idx]
248
  chkbox_label = first_name+' (1/'+str(state_obj["totalFillingNum"]+1)+')'
249
  return {state_json : state_obj,
250
- chs_chkbox : gr.CheckboxGroup(choices=in_channels, label=chkbox_label),
251
  next_btn : gr.Button(interactive=True)}
252
  else:
253
- return {state_json : gr.JSON()}
254
 
255
 
256
  map_btn.click(
257
  fn = reset_layout,
258
  inputs = in_raw_data,
259
- outputs = [state_json, accordion, chs_chkbox, next_btn, run_btn, tpl_montage, map_montage, in_montage, miss_txtbox,
260
  res_md, tpl_loc_file]
261
 
262
  ).success(
@@ -267,67 +295,79 @@ with gr.Blocks() as demo:
267
  ).success(
268
  fn = mapping_result,
269
  inputs = [state_json, channels_json, in_raw_data, in_fill_mode],
270
- outputs = [state_json, accordion, miss_txtbox, res_md, tpl_loc_file, run_btn]
271
 
272
  ).success(
273
  fn = show_montage,
274
  inputs = [state_json, in_raw_loc],
275
- outputs = [in_montage, tpl_montage, map_montage]
276
 
277
  ).success(
278
  fn = generate_chkbox,
279
  inputs = state_json,
280
  outputs = [state_json, chs_chkbox, next_btn]
 
 
 
 
 
281
  )
282
 
283
 
284
  def check_next(state_obj, selected, raw_data, fill_mode):
285
  if state_obj["state"] == "selecting":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  if state_obj["fillingCount"] <= state_obj["totalFillingNum"]:
 
 
 
 
287
 
288
- # info before clicking on next_btn
289
- prev_target_idx = state_obj["missingChannelsIndex"][state_obj["fillingCount"]]
290
- prev_target_name = state_obj["templateByIndex"][prev_target_idx]
291
-
292
- selected_idx = [state_obj["inputByName"][channel]["index"] for channel in selected]
293
- state_obj["newOrder"][prev_target_idx] = selected_idx
294
-
295
- print('Selection for missing channel "{}"({}): {}'.format(prev_target_name, prev_target_idx, selected))
296
 
297
- # update next round
298
- state_obj["fillingCount"] += 1
299
- if state_obj["fillingCount"] <= state_obj["totalFillingNum"]:
300
- target_idx = state_obj["missingChannelsIndex"][state_obj["fillingCount"]]
301
- target_name = state_obj["templateByIndex"][target_idx]
302
- chkbox_label = target_name+' ('+str(state_obj["fillingCount"]+1)+'/'+str(state_obj["totalFillingNum"]+1)+')'
303
- btn_label = "Submit" if state_obj["fillingCount"]==state_obj["totalFillingNum"] else "Next"
304
-
305
- return {state_json : state_obj,
306
- chs_chkbox : gr.CheckboxGroup(value=[], label=chkbox_label),
307
- next_btn : gr.Button(btn_label)}
308
- else:
309
- state_obj["state"] = "finished"
310
- reorder_data(raw_data, state_obj["newOrder"], fill_mode, state_obj)
311
-
312
- missing_channels = [state_obj["templateByIndex"][idx] for idx in state_obj["missingChannelsIndex"]]
313
- missing_channels = ', '.join(missing_channels)
314
 
315
- return {state_json : state_obj,
316
- accordion : gr.Accordion(visible=False),
317
- res_md : gr.Markdown(visible=True),
318
- miss_txtbox : gr.Textbox(value=missing_channels, visible=True),
319
- tpl_loc_file : gr.File(visible=True),
320
- run_btn : gr.Button(interactive=True)}
 
321
 
322
  next_btn.click(
323
  fn = check_next,
324
  inputs = [state_json, chs_chkbox, in_raw_data, in_fill_mode],
325
- outputs = [state_json, accordion, chs_chkbox, next_btn, run_btn, res_md, miss_txtbox, tpl_loc_file]
326
 
327
  ).success(
328
  fn = show_montage,
329
  inputs = [state_json, in_raw_loc],
330
- outputs = [in_montage, tpl_montage, map_montage]
331
  )
332
 
333
 
 
34
  Firstly, we will attempt to find neighboring channel to use as alternative. For instance, if the required channel is **FC3** but you only have **FC1**, we will use it as a replacement for **FC3**.
35
  Then, depending on the **Imputation** way you chose, we will:
36
  - **zero**: fill the missing channels with zeros.
37
+ - **adjacent**: fill the missing channels using neighboring channels which are located closer to the center. For example, if the required channel is **FC3** but you only have **F3, C3**, then we will choose **C3** as the imputing value for **FC3**.
38
  >Note: The imputed channels **need to be removed** after the data being reconstructed.
39
 
40
  ### Mapping result
 
63
  Electroencephalography (EEG) signals are often contaminated with artifacts. It is imperative to develop a practical and reliable artifact removal method to prevent the misinterpretation of neural signals and the underperformance of brain–computer interfaces. Based on the U-Net architecture, we developed a new artifact removal model, IC-U-Net, for removing pervasive EEG artifacts and reconstructing brain signals. IC-U-Net was trained using mixtures of brain and non-brain components decomposed by independent component analysis. It uses an ensemble of loss functions to model complex signal fluctuations in EEG recordings. The effectiveness of the proposed method in recovering brain activities and removing various artifacts (e.g., eye blinks/movements, muscle activities, and line/channel noise) was demonstrated in a simulation study and four real-world EEG experiments. IC-U-Net can reconstruct a multi-channel EEG signal and is applicable to most artifact types, offering a promising end-to-end solution for automatically removing artifacts from EEG recordings. It also meets the increasing need to image natural brain dynamics in a mobile setting.
64
  """
65
 
66
+ chkbox_js = """
67
+ (state_json) => {
68
+ state_json = JSON.parse(JSON.stringify(state_json));
69
+ if(state_json.state == "finished") return;
70
+
71
+ document.querySelector("#chs-chkbox>div:nth-of-type(2)").style.cssText = `
72
+ position: relative;
73
+ width: 560px;
74
+ height: 560px;
75
+ background: url("file=${state_json.files.raw_montage}");
76
+ `;
77
+
78
+ let all_chkbox = document.querySelectorAll("#chs-chkbox> div:nth-of-type(2)> label");
79
+ all_chkbox = Array.apply(null, all_chkbox);
80
+
81
+ all_chkbox.forEach((item, index) => {
82
+ let channel = state_json.inputByIndex[index];
83
+ let left = state_json.inputByName[channel].css_position[0];
84
+ let bottom = state_json.inputByName[channel].css_position[1];
85
+ //console.log(`left: ${left}, bottom: ${bottom}`);
86
+
87
+ item.style.cssText = `
88
+ position: absolute;
89
+ left: ${left};
90
+ bottom: ${bottom};
91
+ `;
92
+ item.className = "";
93
+ item.querySelector("span").innerText = "";
94
+ });
95
+
96
+ }
97
+ """
98
+
99
 
100
  with gr.Blocks() as demo:
101
 
 
104
  with gr.Row():
105
  gr.Markdown(
106
  """
107
+
 
108
  """
109
  )
110
  with gr.Row():
 
132
  """,
133
  visible=False
134
  )
 
 
 
 
 
 
135
  with gr.Row():
136
  tpl_montage = gr.Image("./template_montage.png", label="Template montage", visible=False)
137
  map_montage = gr.Image(label="Choosen channels", visible=False)
138
+ chs_chkbox = gr.CheckboxGroup(elem_id="chs-chkbox", label="", visible=False)
139
+ next_btn = gr.Button("Next", interactive=False, visible=False)
 
 
 
 
 
140
  miss_txtbox = gr.Textbox(label="Missing channels", visible=False)
141
  tpl_loc_file = gr.File("./template_chanlocs.loc", show_label=False, visible=False)
 
142
  with gr.Column():
143
  gr.Markdown(
144
  """
145
+ # 2.Decode Data
146
  """
147
  )
148
  with gr.Row():
 
166
  with gr.Tab("QuickStart"):
167
  gr.Markdown(quickstart)
168
 
169
+ #demo.load(js=js)
170
 
171
  def reset_layout(raw_data):
172
  # establish temp folder
 
177
  utils.dataDelete(filepath+"/temp_data/")
178
  os.mkdir(filepath+"/temp_data/")
179
  #print(e)
180
+ state_obj = {
181
+ "filepath": filepath+"/temp_data/",
182
+ "files": {}
183
+ }
184
+ return {state_json : state_obj,
185
+ chs_chkbox : gr.CheckboxGroup(choices=[], value=[], label="", visible=False), # choices, value ???
186
+ next_btn : gr.Button("Next", interactive=False, visible=False),
187
  run_btn : gr.Button(interactive=False),
188
  tpl_montage : gr.Image(visible=False),
189
+ map_montage : gr.Image(value=None, visible=False),
 
190
  miss_txtbox : gr.Textbox(visible=False),
191
  res_md : gr.Markdown(visible=False),
192
  tpl_loc_file : gr.File(visible=False)}
 
202
  })
203
  #print("Missing channels:", state_obj["missingChannelsIndex"])
204
  return {state_json : state_obj,
205
+ next_btn : gr.Button(visible=True)}
206
  else:
207
  reorder_data(raw_data, channels_obj["newOrder"], fill_mode, state_obj)
208
 
 
223
  def show_montage(state_obj, raw_loc):
224
  filepath = state_obj["filepath"]
225
  raw_montage = read_custom_montage(raw_loc)
226
+
227
+ # convert all channel names to uppercase
228
  for i in range(len(raw_montage.ch_names)):
229
  channel = raw_montage.ch_names[i]
230
  raw_montage.rename_channels({channel: str.upper(channel)})
231
 
232
  if state_obj["state"] == "initializing":
233
  filename = filepath+"raw_montage_"+str(random.randint(1,10000))+".png"
234
+ state_obj["files"]["raw_montage"] = filename
235
  raw_fig = raw_montage.plot()
236
+ raw_fig.set_size_inches(5.6, 5.6)
237
+ raw_fig.savefig(filename, pad_inches=0)
238
 
239
+ return {state_json : state_obj}#,
240
+ #tpl_montage : gr.Image(visible=True),
241
+ #in_montage : gr.Image(value=filename, visible=True),
242
+ #map_montage : gr.Image(visible=False)}
243
 
244
  elif state_obj["state"] == "finished":
245
  # didn't find any way to hide the dark points...
246
  # tmp
247
  filename = filepath+"mapped_montage_"+str(random.randint(1,10000))+".png"
248
+ state_obj["files"]["map_montage"] = filename
249
 
250
  show_names= []
251
  for channel in state_obj["inputByName"]:
 
254
  continue
255
  show_names.append(channel)
256
  mapped_fig = raw_montage.plot(show_names=show_names)
257
+ mapped_fig.set_size_inches(5.6, 5.6)
258
+ mapped_fig.savefig(filename, pad_inches=0)
259
 
260
+ return {state_json : state_obj,
261
+ tpl_montage : gr.Image(visible=True),
262
+ map_montage : gr.Image(value=filename, visible=True)}
263
 
264
  elif state_obj["state"] == "selecting":
265
+ # update in_montage here ?
266
+ #return {in_montage : gr.Image()}
267
+ return {state_json : state_obj}
268
 
269
  def generate_chkbox(state_obj):
270
  if state_obj["state"] == "initializing":
271
  in_channels = [channel for channel in state_obj["inputByName"]]
272
  state_obj["state"] = "selecting"
 
273
 
274
  first_idx = state_obj["missingChannelsIndex"][0]
275
  first_name = state_obj["templateByIndex"][first_idx]
276
  chkbox_label = first_name+' (1/'+str(state_obj["totalFillingNum"]+1)+')'
277
  return {state_json : state_obj,
278
+ chs_chkbox : gr.CheckboxGroup(choices=in_channels, label=chkbox_label, visible=True),
279
  next_btn : gr.Button(interactive=True)}
280
  else:
281
+ return {state_json : state_obj}
282
 
283
 
284
  map_btn.click(
285
  fn = reset_layout,
286
  inputs = in_raw_data,
287
+ outputs = [state_json, chs_chkbox, next_btn, run_btn, tpl_montage, map_montage, miss_txtbox,
288
  res_md, tpl_loc_file]
289
 
290
  ).success(
 
295
  ).success(
296
  fn = mapping_result,
297
  inputs = [state_json, channels_json, in_raw_data, in_fill_mode],
298
+ outputs = [state_json, chs_chkbox, next_btn, miss_txtbox, res_md, tpl_loc_file, run_btn]
299
 
300
  ).success(
301
  fn = show_montage,
302
  inputs = [state_json, in_raw_loc],
303
+ outputs = [state_json, tpl_montage, map_montage]
304
 
305
  ).success(
306
  fn = generate_chkbox,
307
  inputs = state_json,
308
  outputs = [state_json, chs_chkbox, next_btn]
309
+ ).success(
310
+ fn = None,
311
+ js = chkbox_js,
312
+ inputs = state_json,
313
+ outputs = []
314
  )
315
 
316
 
317
  def check_next(state_obj, selected, raw_data, fill_mode):
318
  if state_obj["state"] == "selecting":
319
+
320
+ # save info before clicking on next_btn
321
+ prev_target_idx = state_obj["missingChannelsIndex"][state_obj["fillingCount"]]
322
+ prev_target_name = state_obj["templateByIndex"][prev_target_idx]
323
+
324
+ selected_idx = [state_obj["inputByName"][channel]["index"] for channel in selected]
325
+ state_obj["newOrder"][prev_target_idx] = selected_idx
326
+
327
+ if len(selected)==1 and state_obj["inputByName"][selected[0]]["used"]==False:
328
+ state_obj["inputByName"][selected[0]]["used"] = True
329
+ state_obj["missingChannelsIndex"][state_obj["fillingCount"]] = -1
330
+
331
+ print('Selection for missing channel "{}"({}): {}'.format(prev_target_name, prev_target_idx, selected))
332
+
333
+ # update next round
334
+ state_obj["fillingCount"] += 1
335
  if state_obj["fillingCount"] <= state_obj["totalFillingNum"]:
336
+ target_idx = state_obj["missingChannelsIndex"][state_obj["fillingCount"]]
337
+ target_name = state_obj["templateByIndex"][target_idx]
338
+ chkbox_label = target_name+' ('+str(state_obj["fillingCount"]+1)+'/'+str(state_obj["totalFillingNum"]+1)+')'
339
+ btn_label = "Submit" if state_obj["fillingCount"]==state_obj["totalFillingNum"] else "Next"
340
 
341
+ return {state_json : state_obj,
342
+ chs_chkbox : gr.CheckboxGroup(value=[], label=chkbox_label),
343
+ next_btn : gr.Button(btn_label)}
344
+ else:
345
+ state_obj["state"] = "finished"
346
+ reorder_data(raw_data, state_obj["newOrder"], fill_mode, state_obj)
 
 
347
 
348
+ missing_channels = []
349
+ for idx in state_obj["missingChannelsIndex"]:
350
+ if idx != -1:
351
+ missing_channels.append(state_obj["templateByIndex"][idx])
352
+ missing_channels = ', '.join(missing_channels)
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
+ return {state_json : state_obj,
355
+ chs_chkbox : gr.CheckboxGroup(visible=False),
356
+ next_btn : gr.Button(visible=False),
357
+ res_md : gr.Markdown(visible=True),
358
+ miss_txtbox : gr.Textbox(value=missing_channels, visible=True),
359
+ tpl_loc_file : gr.File(visible=True),
360
+ run_btn : gr.Button(interactive=True)}
361
 
362
  next_btn.click(
363
  fn = check_next,
364
  inputs = [state_json, chs_chkbox, in_raw_data, in_fill_mode],
365
+ outputs = [state_json, chs_chkbox, next_btn, run_btn, res_md, miss_txtbox, tpl_loc_file]
366
 
367
  ).success(
368
  fn = show_montage,
369
  inputs = [state_json, in_raw_loc],
370
+ outputs = [state_json, tpl_montage, map_montage]
371
  )
372
 
373
 
channel_mapping.py CHANGED
@@ -7,7 +7,6 @@ import mne
7
  from mne.channels import read_custom_montage
8
 
9
  def reorder_data(filename, old_idx, fill_mode, state_obj):
10
- #filepath = os.path.dirname(str(filename))
11
  old_data = utils.read_train_data(filename)
12
  new_data = np.zeros((30, old_data.shape[1]))
13
  new_filename = state_obj["filepath"]+'mapped.csv'
@@ -27,21 +26,21 @@ def reorder_data(filename, old_idx, fill_mode, state_obj):
27
  new_data[i, :] = np.mean(tmp_data, axis=0)
28
 
29
  #print('new data shape: ', new_data.shape)
30
- #utils.save_data(new_data, filepath+'/temp_data/mapped.csv')
31
  utils.save_data(new_data, new_filename)
32
  return
33
 
34
 
35
  class Channel:
36
 
37
- def __init__(self, index, name=None, used=False, coord=None, topo_index=None, topo_location=None):
38
 
39
  self.name = name
40
  self.index = index
41
  self.used = used
42
  self.coord = coord
 
43
  self.topo_index = topo_index
44
- self.topo_location = topo_location
45
 
46
  def prefix(self):
47
  ret = ''.join(filter(str.isalpha, self.name))
@@ -52,10 +51,6 @@ class Channel:
52
 
53
 
54
  def pack_data(new_idx, missing_channels, tpl_dict, in_dict, tpl_ordered_name, in_ordered_name):
55
-
56
- # tmp...
57
- for ch in in_dict:
58
- in_dict[ch].coord = None
59
 
60
  return {
61
  "newOrder" : [([i] if i!=-1 else []) for i in new_idx],
@@ -71,32 +66,41 @@ def mapping(data_file, loc_file, fill_mode):
71
 
72
  data = utils.read_train_data(data_file)
73
 
 
 
74
  template_montage = read_custom_montage("./template_chanlocs.loc")
75
  input_montage = read_custom_montage(loc_file)
76
- #template_montage.plot()
77
- #input_montage.plot()
78
 
79
- template_dict = {}
80
- input_dict = {}
81
-
82
- # convert all channel names to uppercase
83
- for i in range(30):
84
- channel = template_montage.ch_names[i]
85
- template_montage.rename_channels({channel: str.upper(channel)})
86
-
87
- channel = str.upper(channel)
88
- template_dict[channel] = Channel(index=i, name=channel)
89
-
90
- for i in range(len(input_montage.ch_names)):
91
- channel = input_montage.ch_names[i]
92
- input_montage.rename_channels({channel: str.upper(channel)})
93
-
94
- channel = str.upper(channel)
95
- input_dict[channel] = Channel(index=i, name=channel, coord=input_montage.get_positions()['ch_pos'][channel])
96
-
97
-
 
 
 
 
 
 
 
 
 
 
98
  new_idx = [-1]*30
99
- #new_idx_name = ['']*30 # tmp
100
  missing_channels = []
101
  exact_missing_channels = []
102
  z_row_idx = data.shape[0]
@@ -113,7 +117,7 @@ def mapping(data_file, loc_file, fill_mode):
113
  'T6': 'P8',
114
  'TP7': 'T5\'',
115
  'TP8': 'T6\'',
116
- }
117
 
118
  for i in range(30):
119
  channel = template_montage.ch_names[i]
@@ -134,16 +138,13 @@ def mapping(data_file, loc_file, fill_mode):
134
  continue
135
 
136
  new_idx[i] = input_dict[channel].index
137
- #new_idx_name[i] = channel # tmp
138
  input_dict[channel].used = True
139
 
140
  if finish_flag == 1:
141
  second2 = time.time()
142
  print('Finish at stage 1 ! (',second2 - second1,'s)')
143
- print('new idx order:', new_idx)
144
- #print('new_idx_name:', new_idx_name) # tmp
145
 
146
- #reorder_data(input_file, new_idx, fill_mode)
147
  channels_obj = pack_data(new_idx, [],
148
  template_dict, input_dict,
149
  template_montage.ch_names, input_montage.ch_names)
@@ -180,7 +181,7 @@ def mapping(data_file, loc_file, fill_mode):
180
  ver = 'front' if i<3 else 'center' if i==3 else 'back'
181
  hor = 'left' if j<2 else 'center' if j==2 else 'right'
182
  template_dict[channel].topo_index = [i, j]
183
- template_dict[channel].topo_location = [ver, hor]
184
 
185
  if i > 1 and j in [0, 4]:
186
  temporal_channels.append(channel)
@@ -217,8 +218,8 @@ def mapping(data_file, loc_file, fill_mode):
217
 
218
  curr_row = template_dict[channel].topo_index[0]
219
  curr_col = template_dict[channel].topo_index[1]
220
- curr_ver = template_dict[channel].topo_location[0]
221
- curr_hor = template_dict[channel].topo_location[1]
222
 
223
  impute_channel = ''
224
 
@@ -257,7 +258,6 @@ def mapping(data_file, loc_file, fill_mode):
257
  elif curr_hor == 'left' or curr_hor == 'right':
258
 
259
  ver_ctrl = 1 if curr_ver=='front' else 2 if curr_ver=='back' else 3 # bit0: row+1, bit1: row-1
260
- #ver_dir = 1 if curr_ver == 'front' else -1
261
 
262
  # search horizontally
263
  cnt = 0
@@ -293,16 +293,13 @@ def mapping(data_file, loc_file, fill_mode):
293
  impute_channel = 'CZ'
294
 
295
  new_idx[i] = input_dict[impute_channel].index
296
- #new_idx_name[i] = impute_channel # tmp
297
  if input_dict[impute_channel].used == True: # this channel is shared with others
298
  missing_channels.append(i)
299
  input_dict[impute_channel].used = True
300
 
301
  second2 = time.time()
302
  print('Finish at stage 2 ! (',second2 - second1,'s)')
303
- print('new_idx:', new_idx)
304
- #print('missing_channels:', missing_channels)
305
- #reorder_data(input_file, new_idx, fill_mode)
306
 
307
  channels_obj = pack_data(new_idx, missing_channels,
308
  template_dict, input_dict,
 
7
  from mne.channels import read_custom_montage
8
 
9
  def reorder_data(filename, old_idx, fill_mode, state_obj):
 
10
  old_data = utils.read_train_data(filename)
11
  new_data = np.zeros((30, old_data.shape[1]))
12
  new_filename = state_obj["filepath"]+'mapped.csv'
 
26
  new_data[i, :] = np.mean(tmp_data, axis=0)
27
 
28
  #print('new data shape: ', new_data.shape)
 
29
  utils.save_data(new_data, new_filename)
30
  return
31
 
32
 
33
  class Channel:
34
 
35
+ def __init__(self, index, name=None, used=False, coord=None, css_position=None, topo_index=None, topo_position=None):
36
 
37
  self.name = name
38
  self.index = index
39
  self.used = used
40
  self.coord = coord
41
+ self.css_position = css_position
42
  self.topo_index = topo_index
43
+ self.topo_position = topo_position
44
 
45
  def prefix(self):
46
  ret = ''.join(filter(str.isalpha, self.name))
 
51
 
52
 
53
  def pack_data(new_idx, missing_channels, tpl_dict, in_dict, tpl_ordered_name, in_ordered_name):
 
 
 
 
54
 
55
  return {
56
  "newOrder" : [([i] if i!=-1 else []) for i in new_idx],
 
66
 
67
  data = utils.read_train_data(data_file)
68
 
69
+ template_dict = {}
70
+ input_dict = {}
71
  template_montage = read_custom_montage("./template_chanlocs.loc")
72
  input_montage = read_custom_montage(loc_file)
 
 
73
 
74
+ montages = [template_montage, input_montage]
75
+ dicts = [template_dict, input_dict]
76
+ num = [30, len(input_montage.ch_names)]
77
+
78
+ for i in range(2):
79
+ fig = montages[i].plot()
80
+ fig.set_size_inches(5.6, 5.6)
81
+ ax = fig.axes[0]
82
+ ax.set_aspect('equal')
83
+ ax.figure.canvas.draw() #update the figure
84
+ coords = ax.collections[0].get_offsets().data
85
+ abs_coords = ax.transData.transform(coords)
86
+ #print("abs_coords)
87
+ for j in range(num[i]):
88
+ channel = montages[i].ch_names[j]
89
+
90
+ # convert all channel names to uppercase
91
+ montages[i].rename_channels({channel: str.upper(channel)})
92
+
93
+ css_left = (abs_coords[j][0]-11)/560
94
+ css_bottom = (abs_coords[j][1]-7)/560
95
+ channel = str.upper(channel)
96
+ dicts[i][channel] = Channel(index=j,
97
+ name=channel,
98
+ coord=montages[i].get_positions()['ch_pos'][channel],
99
+ css_position=[str(round(css_left*100, 2))+"%", str(round(css_bottom*100, 2))+"%"]
100
+ )
101
+
102
+
103
  new_idx = [-1]*30
 
104
  missing_channels = []
105
  exact_missing_channels = []
106
  z_row_idx = data.shape[0]
 
117
  'T6': 'P8',
118
  'TP7': 'T5\'',
119
  'TP8': 'T6\'',
120
+ }
121
 
122
  for i in range(30):
123
  channel = template_montage.ch_names[i]
 
138
  continue
139
 
140
  new_idx[i] = input_dict[channel].index
 
141
  input_dict[channel].used = True
142
 
143
  if finish_flag == 1:
144
  second2 = time.time()
145
  print('Finish at stage 1 ! (',second2 - second1,'s)')
146
+ #print('new idx order:', new_idx)
 
147
 
 
148
  channels_obj = pack_data(new_idx, [],
149
  template_dict, input_dict,
150
  template_montage.ch_names, input_montage.ch_names)
 
181
  ver = 'front' if i<3 else 'center' if i==3 else 'back'
182
  hor = 'left' if j<2 else 'center' if j==2 else 'right'
183
  template_dict[channel].topo_index = [i, j]
184
+ template_dict[channel].topo_position = [ver, hor]
185
 
186
  if i > 1 and j in [0, 4]:
187
  temporal_channels.append(channel)
 
218
 
219
  curr_row = template_dict[channel].topo_index[0]
220
  curr_col = template_dict[channel].topo_index[1]
221
+ curr_ver = template_dict[channel].topo_position[0]
222
+ curr_hor = template_dict[channel].topo_position[1]
223
 
224
  impute_channel = ''
225
 
 
258
  elif curr_hor == 'left' or curr_hor == 'right':
259
 
260
  ver_ctrl = 1 if curr_ver=='front' else 2 if curr_ver=='back' else 3 # bit0: row+1, bit1: row-1
 
261
 
262
  # search horizontally
263
  cnt = 0
 
293
  impute_channel = 'CZ'
294
 
295
  new_idx[i] = input_dict[impute_channel].index
 
296
  if input_dict[impute_channel].used == True: # this channel is shared with others
297
  missing_channels.append(i)
298
  input_dict[impute_channel].used = True
299
 
300
  second2 = time.time()
301
  print('Finish at stage 2 ! (',second2 - second1,'s)')
302
+ #print('new_idx:', new_idx)
 
 
303
 
304
  channels_obj = pack_data(new_idx, missing_channels,
305
  template_dict, input_dict,