audrey06100 commited on
Commit
ef20573
·
1 Parent(s): 995c1d0
Files changed (2) hide show
  1. app.py +344 -190
  2. channel_mapping.py +27 -32
app.py CHANGED
@@ -4,7 +4,7 @@ import os
4
  import random
5
  import math
6
  import utils
7
- from channel_mapping import mapping_stage1, mapping_stage2, reorder_to_template, reorder_to_origin
8
 
9
  import mne
10
  from mne.channels import read_custom_montage
@@ -60,8 +60,7 @@ chkbox_js = """
60
 
61
 
62
  // add indication for the missing channels
63
- let channel = channel_info.missingChannelsIndex[0]
64
- channel = channel_info.templateByIndex[channel]
65
  let left = channel_info.templateByName[channel].css_position[0];
66
  let bottom = channel_info.templateByName[channel].css_position[1];
67
 
@@ -120,8 +119,7 @@ indication_js = """
120
  channel_info = JSON.parse(JSON.stringify(channel_info));
121
  if(app_state.state == "finished") return;
122
 
123
- let channel = channel_info.missingChannelsIndex[app_state["fillingCount"]-1]
124
- channel = channel_info.templateByIndex[channel]
125
  let left = channel_info.templateByName[channel].css_position[0];
126
  let bottom = channel_info.templateByName[channel].css_position[1];
127
 
@@ -169,51 +167,46 @@ with gr.Blocks() as demo:
169
  with gr.Row():
170
 
171
  with gr.Column():
172
- gr.Markdown(
173
- """
174
- # 1.Channel Mapping
175
- """
176
- )
177
-
178
- # upload files, chose imputation way (???
179
  with gr.Row():
180
  in_raw_data = gr.File(label="Raw data (.csv)", file_types=[".csv"])
181
  in_raw_loc = gr.File(label="Channel locations (.loc, .locs)", file_types=[".loc", "locs"])
182
- with gr.Column(min_width=100):
183
- in_sample_rate = gr.Textbox(label="Sampling rate (Hz)")
184
- in_fill_mode = gr.Dropdown(choices=[
185
- #("adjacent channel", "adjacent"),
186
- ("mean (auto)", "mean_auto"),
187
- ("mean (manual)", "mean_manual"),
188
- ("",""),
189
- "zero"],
190
- value="mean_auto",
191
- label="Imputation")
192
  map_btn = gr.Button("Mapping")
193
 
194
- chkbox_group = gr.CheckboxGroup(elem_id="chkbox-group", label="", visible=False)
195
- next_btn = gr.Button("Next", interactive=False, visible=False)
 
196
 
197
- # mapping result
198
- res_md = gr.Markdown(
199
- """
200
- ### Mapping result:
201
- """,
202
- visible=False
203
- )
204
  with gr.Row():
205
  tpl_montage = gr.Image("./template_montage.png", label="Template montage", visible=False)
206
- map_montage = gr.Image(label="Matched channels", visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
- #miss_txtbox = gr.Textbox(label="Missing channels", visible=False)
209
- #tpl_loc_file = gr.File("./template_chanlocs.loc", show_label=False, visible=False)
210
 
211
  with gr.Column():
212
- gr.Markdown(
213
- """
214
- # 2.Decode Data
215
- """
216
- )
217
  with gr.Row():
218
  in_model_name = gr.Dropdown(choices=[
219
  ("ART", "EEGART"),
@@ -226,9 +219,16 @@ with gr.Blocks() as demo:
226
  label="Model",
227
  scale=2)
228
  run_btn = gr.Button(scale=1, interactive=False)
 
 
229
  batch_md = gr.Markdown(visible=False)
230
  out_denoised_data = gr.File(label="Denoised data", visible=False)
231
-
 
 
 
 
 
232
 
233
  with gr.Row():
234
  with gr.Tab("ART"):
@@ -244,7 +244,16 @@ with gr.Blocks() as demo:
244
 
245
  #demo.load(js=js)
246
 
247
- def reset1(raw_data, samplerate):
 
 
 
 
 
 
 
 
 
248
  # establish temp folder
249
  filepath = os.path.dirname(str(raw_data))
250
  try:
@@ -255,216 +264,361 @@ with gr.Blocks() as demo:
255
  #print(e)
256
 
257
  # initialize app_state, channel_info
258
- data = utils.read_train_data(raw_data)
259
  app_state = {
260
  "filepath": filepath+"/temp_data/",
261
  "filenames": {},
262
  "sampleRate": int(samplerate),
263
-
264
  }
265
  channel_info = {
266
- "dataShape" : data.shape
267
  }
268
 
 
269
  return {app_state_json : app_state,
270
  channel_info_json : channel_info,
271
- chkbox_group : gr.CheckboxGroup(choices=[], value=[], label="", visible=False),
272
- next_btn : gr.Button("Next", interactive=False, visible=False),
273
- run_btn : gr.Button(interactive=False),
274
  tpl_montage : gr.Image(visible=False),
275
  map_montage : gr.Image(value=None, visible=False),
276
- res_md : gr.Markdown(visible=False),
 
 
 
 
 
 
 
 
277
  batch_md : gr.Markdown(visible=False),
278
  out_denoised_data : gr.File(visible=False)}
279
-
280
- def mapping_result(app_state, channel_info, fill_mode):
281
 
282
- in_num = len(channel_info["inputByName"])
283
- matched_num = 30 - len(channel_info["missingChannelsIndex"])
284
- batch_num = math.ceil((in_num-matched_num)/30) + 1
285
- app_state.update({
286
- "batchCount" : 1,
287
- "totalBatchNum" : batch_num
288
- })
289
-
290
- if fill_mode=="mean_manual" and channel_info["missingChannelsIndex"]!=[]:
291
- app_state.update({
292
- "state" : "initializing",
293
- "totalFillingNum" : len(channel_info["missingChannelsIndex"])
294
- })
295
- #print("Missing channels:", channel_info["missingChannelsIndex"])
296
- return {app_state_json : app_state,
297
- next_btn : gr.Button(visible=True)}
298
- else:
299
- app_state.update({
300
- "state" : "finished"
301
- })
302
- return {app_state_json : app_state,
303
- res_md : gr.Markdown(visible=True),
304
- run_btn : gr.Button(interactive=True)}
305
-
306
- def show_montage(app_state, channel_info, raw_loc):
307
- if app_state["state"] == "selecting":
308
- return {app_state_json : app_state} # change nothing
309
-
310
  filepath = app_state["filepath"]
 
 
 
311
  raw_montage = read_custom_montage(raw_loc)
 
 
 
312
 
313
- # convert all channel names to uppercase
314
- for i in range(len(raw_montage.ch_names)):
315
- channel = raw_montage.ch_names[i]
316
- raw_montage.rename_channels({channel: str.upper(channel)})
317
-
318
- if app_state["state"] == "initializing":
319
- filename = filepath+"raw_montage_"+str(random.randint(1,10000))+".png"
320
- app_state["filenames"]["raw_montage"] = filename
321
- raw_fig = raw_montage.plot()
322
- raw_fig.set_size_inches(5.6, 5.6)
323
- raw_fig.savefig(filename, pad_inches=0)
324
-
325
- return {app_state_json : app_state}
326
 
327
- elif app_state["state"] == "finished":
328
- filename = filepath+"mapped_montage_"+str(random.randint(1,10000))+".png"
329
- app_state["filenames"]["map_montage"] = filename
330
-
331
- show_names= []
332
- for channel in channel_info["inputByName"]:
333
- if channel_info["inputByName"][channel]["matched"]:
334
- show_names.append(channel)
335
- mapped_fig = raw_montage.plot(show_names=show_names)
336
- mapped_fig.set_size_inches(5.6, 5.6)
337
- mapped_fig.savefig(filename, pad_inches=0)
 
338
 
339
  return {app_state_json : app_state,
 
340
  tpl_montage : gr.Image(visible=True),
341
- map_montage : gr.Image(value=filename, visible=True)}
342
-
343
- #else:
344
- #return {app_state_json : app_state} # change nothing
345
-
346
- def generate_chkbox(app_state, channel_info):
347
- if app_state["state"] == "initializing":
348
- in_channels = [channel for channel in channel_info["inputByName"]]
349
- app_state["state"] = "selecting"
350
- app_state["fillingCount"] = 1
351
-
352
- idx = channel_info["missingChannelsIndex"][0]
353
- name = channel_info["templateByIndex"][idx]
354
- chkbox_label = name+' (1/'+str(app_state["totalFillingNum"])+')'
355
- return {app_state_json : app_state,
356
- chkbox_group : gr.CheckboxGroup(choices=in_channels, label=chkbox_label, visible=True),
357
- next_btn : gr.Button(interactive=True)}
358
- else:
359
- return {app_state_json : app_state} # change nothing
360
-
361
-
362
- map_btn.click(
363
- fn = reset1,
364
- inputs = [in_raw_data, in_sample_rate],
365
- outputs = [app_state_json, channel_info_json, chkbox_group, next_btn, run_btn,
366
- tpl_montage, map_montage, res_md, batch_md, out_denoised_data]
367
-
368
- ).success(
369
- fn = mapping_stage1,
370
- inputs = [app_state_json, channel_info_json, in_raw_data, in_raw_loc, in_fill_mode],
371
- outputs = [app_state_json, channel_info_json]
372
 
373
- ).success(
374
- fn = mapping_result,
375
- inputs = [app_state_json, channel_info_json, in_fill_mode],
376
- outputs = [app_state_json, next_btn, res_md, run_btn]
377
 
378
- ).success(
379
- fn = show_montage,
380
- inputs = [app_state_json, channel_info_json, in_raw_loc],
381
- outputs = [app_state_json, tpl_montage, map_montage]
382
 
 
 
 
 
 
 
 
 
 
 
 
383
  ).success(
384
- fn = generate_chkbox,
385
- inputs = [app_state_json, channel_info_json],
386
- outputs = [app_state_json, chkbox_group, next_btn]
387
-
388
  ).success(
389
- fn = None,
390
- js = chkbox_js,
391
- inputs = [app_state_json, channel_info_json],
392
- outputs = []
393
  )
394
-
395
 
396
- def check_next(app_state, channel_info, selected, raw_data, fill_mode):
397
- #if state["state"] == "selecting":
398
-
399
- # save info before clicking on next_btn
400
- prev_target_idx = channel_info["missingChannelsIndex"][app_state["fillingCount"]-1]
401
- prev_target_name = channel_info["templateByIndex"][prev_target_idx]
402
 
403
- selected_idx = [channel_info["inputByName"][channel]["index"] for channel in selected]
404
- app_state["stage1NewOrder"][prev_target_idx] = selected_idx
 
 
 
 
405
 
406
- #if len(selected)==1 and channel_info["inputByName"][selected[0]]["used"]==False:
407
- #channel_info["inputByName"][selected[0]]["used"] = True
408
- #channel_info["missingChannelsIndex"][state["fillingCount"]-1] = -1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
- print('Selection for missing channel "{}"({}): {}'.format(prev_target_name, prev_target_idx, selected))
 
 
 
 
 
 
 
 
 
411
 
412
- # update next round
413
- app_state["fillingCount"] += 1
414
 
415
- if app_state["fillingCount"] <= app_state["totalFillingNum"]:
416
- target_idx = channel_info["missingChannelsIndex"][app_state["fillingCount"]-1]
417
- target_name = channel_info["templateByIndex"][target_idx]
 
 
 
 
418
 
419
- chkbox_label = target_name+' ('+str(app_state["fillingCount"])+'/'+str(app_state["totalFillingNum"])+')'
420
- btn_label = "Submit" if app_state["fillingCount"]==app_state["totalFillingNum"] else "Next"
 
421
 
422
- return {app_state_json : app_state,
423
- #channel_info_json : channel_info,
424
- chkbox_group : gr.CheckboxGroup(value=[], label=chkbox_label),
425
- next_btn : gr.Button(btn_label)}
426
- else:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  app_state["state"] = "finished"
 
 
 
 
 
 
 
 
 
 
 
428
 
429
  return {app_state_json : app_state,
430
- #channel_info_json : channel_info,
431
  chkbox_group : gr.CheckboxGroup(visible=False),
432
  next_btn : gr.Button(visible=False),
433
- res_md : gr.Markdown(visible=True),
434
  run_btn : gr.Button(interactive=True)}
435
 
436
  next_btn.click(
437
- fn = check_next,
438
- inputs = [app_state_json, channel_info_json, chkbox_group, in_raw_data, in_fill_mode],
439
- outputs = [app_state_json, chkbox_group, next_btn, run_btn, res_md]
 
 
 
 
 
 
 
440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  ).success(
442
- fn = show_montage,
443
- inputs = [app_state_json, channel_info_json, in_raw_loc],
444
- outputs = [app_state_json, tpl_montage, map_montage]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  ).success(
447
- fn = None,
448
- js = indication_js,
449
- inputs = [app_state_json, channel_info_json],
450
  outputs = []
451
  )
452
 
 
453
  def delete_file(filename):
454
  try:
455
  os.remove(filename)
456
  except OSError as e:
457
  print(e)
458
 
459
- def reset2(app_state, raw_data, model_name):
460
  filepath = app_state["filepath"]
461
  input_name = os.path.basename(str(raw_data))
462
  output_name = os.path.splitext(input_name)[0]+'_'+model_name+'.csv'
463
 
 
 
 
 
 
464
  app_state["filenames"]["denoised"] = filepath + output_name
465
  app_state.update({
466
  "runnigState" : "stage1",
467
  "batchCount" : 1,
 
468
  "stage2NewOrder" : [[]]*30
469
  })
470
 
@@ -491,7 +645,6 @@ with gr.Blocks() as demo:
491
  app_state, channel_info = mapping_stage2(app_state, channel_info, fill_mode)
492
  if app_state["runnigState"] == "finished":
493
  break
494
- app_state["batchCount"] += 1
495
 
496
  reorder_to_template(app_state, raw_data)
497
  # step1: Data preprocessing
@@ -507,14 +660,15 @@ with gr.Blocks() as demo:
507
 
508
  delete_file(filepath+'mapped.csv')
509
  delete_file(filepath+'denoised.csv')
 
510
 
511
  yield {run_btn : gr.Button(interactive=True),
512
  batch_md : gr.Markdown(visible=False),
513
  out_denoised_data : gr.File(new_filename, visible=True)}
514
 
515
  run_btn.click(
516
- fn = reset2,
517
- inputs = [app_state_json, in_raw_data, in_model_name],
518
  outputs = [app_state_json, run_btn, batch_md, out_denoised_data]
519
 
520
  ).success(
@@ -524,4 +678,4 @@ with gr.Blocks() as demo:
524
  )
525
 
526
  if __name__ == "__main__":
527
- demo.launch()
 
4
  import random
5
  import math
6
  import utils
7
+ from channel_mapping import mapping_stage1, mapping_stage2, reorder_to_template, reorder_to_origin, find_neighbors
8
 
9
  import mne
10
  from mne.channels import read_custom_montage
 
60
 
61
 
62
  // add indication for the missing channels
63
+ let channel = channel_info.missingChannels[0]
 
64
  let left = channel_info.templateByName[channel].css_position[0];
65
  let bottom = channel_info.templateByName[channel].css_position[1];
66
 
 
119
  channel_info = JSON.parse(JSON.stringify(channel_info));
120
  if(app_state.state == "finished") return;
121
 
122
+ let channel = channel_info.missingChannels[app_state["fillingCount"]-1]
 
123
  let left = channel_info.templateByName[channel].css_position[0];
124
  let bottom = channel_info.templateByName[channel].css_position[1];
125
 
 
167
  with gr.Row():
168
 
169
  with gr.Column():
170
+ gr.Markdown("# 1.Channel Mapping")
171
+ # ------------------------input--------------------------
 
 
 
 
 
172
  with gr.Row():
173
  in_raw_data = gr.File(label="Raw data (.csv)", file_types=[".csv"])
174
  in_raw_loc = gr.File(label="Channel locations (.loc, .locs)", file_types=[".loc", "locs"])
175
+ with gr.Column(): #min_width=100
176
+ in_samplerate = gr.Textbox(label="Sampling rate (Hz)")
 
 
 
 
 
 
 
 
177
  map_btn = gr.Button("Mapping")
178
 
179
+ # ------------------------mapping------------------------
180
+ # description for step123
181
+ desc_md = gr.Markdown("### Mapping result:", visible=False) # """??? # test
182
 
183
+ # step1 : mapping result
 
 
 
 
 
 
184
  with gr.Row():
185
  tpl_montage = gr.Image("./template_montage.png", label="Template montage", visible=False)
186
+ map_montage = gr.Image(label="Input channels", visible=False)
187
+
188
+ # step2 : assign unmatched input channels to empty template channels
189
+ radio = gr.Radio(elem_id="radio", visible=False) #, label=""
190
+ step2_btn = gr.Button("Next", visible=False) #, interactive=False
191
+
192
+ # step3 : select a way to fill the empty template channels
193
+ with gr.Row():
194
+ in_fill_mode = gr.Dropdown(choices=["mean", "zero"],
195
+ value="mean",
196
+ label="Imputation", #......
197
+ visible=False,
198
+ scale=2)
199
+ fillmode_btn = gr.Button("OK", visible=False, scale=1)
200
+
201
+ chkbox_group = gr.CheckboxGroup(elem_id="chkbox-group", label="", visible=False)
202
+ step3_btn = gr.Button("Next", visible=False)
203
+ next_btn = gr.Button("Next step", visible=False)
204
 
205
+ # -------------------------------------------------------
 
206
 
207
  with gr.Column():
208
+ gr.Markdown("# 2.Decode Data")
209
+ # ------------------------input--------------------------
 
 
 
210
  with gr.Row():
211
  in_model_name = gr.Dropdown(choices=[
212
  ("ART", "EEGART"),
 
219
  label="Model",
220
  scale=2)
221
  run_btn = gr.Button(scale=1, interactive=False)
222
+
223
+ # ------------------------output-------------------------
224
  batch_md = gr.Markdown(visible=False)
225
  out_denoised_data = gr.File(label="Denoised data", visible=False)
226
+
227
+ #files = []
228
+ #for i in range():
229
+ #f = gr.File()
230
+ #files.append(f)
231
+ # -------------------------------------------------------
232
 
233
  with gr.Row():
234
  with gr.Tab("ART"):
 
244
 
245
  #demo.load(js=js)
246
 
247
+ # click on mapping button
248
+ def reset_all(raw_data, raw_loc, samplerate):
249
+ # verify that all required inputs have been provided
250
+ if raw_data == None or raw_loc == None:
251
+ gr.Warning('Please upload both the raw data and the channel location files.')
252
+ return
253
+ if samplerate == "":
254
+ gr.Warning('Please enter the sampling rate.')
255
+ return
256
+
257
  # establish temp folder
258
  filepath = os.path.dirname(str(raw_data))
259
  try:
 
264
  #print(e)
265
 
266
  # initialize app_state, channel_info
267
+ #data = utils.read_train_data(raw_data)
268
  app_state = {
269
  "filepath": filepath+"/temp_data/",
270
  "filenames": {},
271
  "sampleRate": int(samplerate),
272
+ "state" : "step1"
273
  }
274
  channel_info = {
275
+ #"dataShape" : data.shape
276
  }
277
 
278
+ # reset layout
279
  return {app_state_json : app_state,
280
  channel_info_json : channel_info,
281
+ # ------------------Stage1-----------------------
282
+ desc_md : gr.Markdown(visible=False),# res_md
 
283
  tpl_montage : gr.Image(visible=False),
284
  map_montage : gr.Image(value=None, visible=False),
285
+ radio : gr.Radio(choices=[], value=[], label="", visible=False),
286
+ in_fill_mode : gr.Dropdown(visible=False),
287
+ chkbox_group : gr.CheckboxGroup(choices=[], value=[], label="", visible=False),
288
+ fillmode_btn : gr.Button("OK", visible=False),
289
+ step2_btn : gr.Button("Next", visible=False),
290
+ step3_btn : gr.Button("Next", visible=False),
291
+ next_btn : gr.Button("Next step", visible=False),
292
+ # ------------------Stage2-----------------------
293
+ run_btn : gr.Button(interactive=False),
294
  batch_md : gr.Markdown(visible=False),
295
  out_denoised_data : gr.File(visible=False)}
 
 
296
 
297
+ # step1
298
+ def mapping_result(app_state, channel_info, raw_loc):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  filepath = app_state["filepath"]
300
+ filename = filepath+"raw_montage_"+str(random.randint(1,10000))+".png"
301
+ app_state["filenames"]["raw_montage"] = filename
302
+
303
  raw_montage = read_custom_montage(raw_loc)
304
+ raw_fig = raw_montage.plot()
305
+ raw_fig.set_size_inches(5.6, 5.6)
306
+ raw_fig.savefig(filename, pad_inches=0)
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
+ #################################
310
+ #### determine the next step ####
311
+ #################################
312
+
313
+ in_num = len(channel_info["inputByName"])
314
+ matched_num = 30 - len(channel_info["missingChannels"])
315
+
316
+ # if the input channels(>=30) has all the 30 template channels
317
+ # -> Stage2.decode data
318
+ if matched_num == 30:
319
+ app_state["state"] = "finished"
320
+ gr.Info('The mapping process is finished!')
321
 
322
  return {app_state_json : app_state,
323
+ desc_md : gr.Markdown("### Mapping result", visible=True),
324
  tpl_montage : gr.Image(visible=True),
325
+ map_montage : gr.Image(value=filename, visible=True),
326
+ run_btn : gr.Button(interactive=True)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
+ # if matched channels < 30, and there're still some unmatched input channels
329
+ # -> assign these input channels to nearby unmatched/empty template channels
330
+ if in_num > matched_num:
331
+ app_state["state"] = "step2-initializing"
332
 
333
+ # if input channels < 30, but all of them can match to some template channels
334
+ # -> directly use fill_mode to fill the remaining channels
335
+ if in_num == matched_num:
336
+ app_state["state"] = "step3-initializing"
337
 
338
+ return {app_state_json : app_state,
339
+ desc_md : gr.Markdown("### Mapping result", visible=True),
340
+ tpl_montage : gr.Image(visible=True),
341
+ map_montage : gr.Image(value=filename, visible=True),
342
+ next_btn : gr.Button("Next step", visible=True)}
343
+
344
+ map_btn.click(
345
+ fn = reset_all,
346
+ inputs = [in_raw_data, in_raw_loc, in_samplerate],
347
+ outputs = [app_state_json, channel_info_json, desc_md, tpl_montage, map_montage, radio, in_fill_mode,
348
+ chkbox_group, fillmode_btn, step2_btn, step3_btn, next_btn, run_btn, batch_md, out_denoised_data]
349
  ).success(
350
+ fn = mapping_stage1,
351
+ inputs = [app_state_json, channel_info_json, in_raw_loc],
352
+ outputs = [app_state_json, channel_info_json, desc_md]
353
+
354
  ).success(
355
+ fn = mapping_result,
356
+ inputs = [app_state_json, channel_info_json, in_raw_loc],
357
+ outputs = [app_state_json, desc_md, tpl_montage, map_montage, next_btn, run_btn]
 
358
  )
359
+
360
 
361
+ def init_next_step(app_state, channel_info, selected_radio, selected_chkbox):
 
 
 
 
 
362
 
363
+ channel_info["missingChannels"] = [channel for channel in channel_info["templateByName"]
364
+ if channel_info["templateByName"][channel]["matched"]==False]
365
+ app_state.update({
366
+ "fillingCount" : 1,
367
+ "totalFillingNum" : len(channel_info["missingChannels"])
368
+ })
369
 
370
+ # step1 -> step2
371
+ if app_state["state"] == "step2-initializing":
372
+ app_state["state"] = "step2-selecting"
373
+
374
+ name = channel_info["missingChannels"][0]
375
+ label = name+' (1/'+str(app_state["totalFillingNum"])+')'
376
+
377
+ unassigned = [channel for channel in channel_info["inputByName"]
378
+ if channel_info["inputByName"][channel]["assigned"]==False]
379
+ if len(unassigned)==1 or app_state["totalFillingNum"]==1:
380
+ btn_label = "Next step"
381
+ else:
382
+ btn_label = "Next"
383
+
384
+ return {app_state_json : app_state,
385
+ channel_info_json : channel_info,
386
+ desc_md : gr.Markdown("### step2"),
387
+ tpl_montage : gr.Image(visible=False),
388
+ map_montage : gr.Image(visible=False),
389
+ radio : gr.Radio(choices=unassigned, value=[], label=label, visible=True),
390
+ step2_btn : gr.Button(btn_label, visible=True),
391
+ next_btn : gr.Button(visible=False)}
392
 
393
+ # step1 -> step3
394
+ elif app_state["state"] == "step3-initializing":
395
+
396
+ return {app_state_json : app_state,
397
+ desc_md : gr.Markdown("### step3"),
398
+ tpl_montage : gr.Image(visible=False),
399
+ map_montage : gr.Image(visible=False),
400
+ in_fill_mode : gr.Dropdown(visible=True),
401
+ fillmode_btn : gr.Button(visible=True),
402
+ next_btn : gr.Button(visible=False)}
403
 
404
+ # step2 -> step3/Stage2.decode data
405
+ elif app_state["state"] == "step2-selecting":
406
 
407
+ # save info before clicking on next_btn
408
+ if selected_radio != []:
409
+ prev_target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
410
+ prev_target_idx = channel_info["templateByName"][prev_target_name]["index"]
411
+
412
+ selected_idx = channel_info["inputByName"][selected_radio]["index"]
413
+ app_state["stage1NewOrder"][prev_target_idx] = [selected_idx]
414
 
415
+ channel_info["templateByName"][prev_target_name]["matched"] = True
416
+ channel_info["inputByName"][selected_radio]["assigned"] = True
417
+ print(prev_target_name, '<-', selected_radio)
418
 
419
+ # if all the unmatched template channels were filled by input channels
420
+ # -> Stage2
421
+ if app_state["fillingCount"] == app_state["totalFillingNum"]:
422
+ app_state["state"] = "finished"
423
+ gr.Info('The mapping process is finished!')
424
+
425
+ return {app_state_json : app_state,
426
+ channel_info_json : channel_info,
427
+ desc_md : gr.Markdown(visible=False),
428
+ radio : gr.Radio(visible=False),
429
+ next_btn : gr.Button(visible=False),
430
+ run_btn : gr.Button(interactive=True)}
431
+
432
+ # -> step3
433
+ else:
434
+ app_state["state"] = "step3-initializing"
435
+
436
+ return {app_state_json : app_state,
437
+ channel_info_json : channel_info,
438
+ desc_md : gr.Markdown("### step3"),
439
+ radio : gr.Radio(visible=False),
440
+ in_fill_mode : gr.Dropdown(visible=True),
441
+ fillmode_btn : gr.Button(visible=True),
442
+ next_btn : gr.Button(visible=False)}
443
+
444
+ # step3 -> Stage2.decode data
445
+ elif app_state["state"] == "step3-selecting":
446
  app_state["state"] = "finished"
447
+ gr.Info('The mapping process is finished!')
448
+
449
+ # save info before clicking on next_btn
450
+ if selected_chkbox != []:
451
+ prev_target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
452
+ prev_target_idx = channel_info["templateByName"][prev_target_name]["index"]
453
+
454
+ selected_idx = [channel_info["inputByName"][channel]["index"] for channel in selected_chkbox]
455
+ app_state["stage1NewOrder"][prev_target_idx] = selected_idx
456
+
457
+ #print('Selection for missing channel "{}"({}): {}'.format(prev_target_name, prev_target_idx, selected))
458
 
459
  return {app_state_json : app_state,
460
+ desc_md : gr.Markdown(visible=False),
461
  chkbox_group : gr.CheckboxGroup(visible=False),
462
  next_btn : gr.Button(visible=False),
 
463
  run_btn : gr.Button(interactive=True)}
464
 
465
  next_btn.click(
466
+ fn = init_next_step,
467
+ inputs = [app_state_json, channel_info_json, radio, chkbox_group],
468
+ outputs = [app_state_json, channel_info_json, desc_md, tpl_montage, map_montage, radio, in_fill_mode,
469
+ chkbox_group, fillmode_btn, step2_btn, next_btn, run_btn]
470
+ ).success(
471
+ fn = None,
472
+ js = indication_js,
473
+ inputs = [app_state_json, channel_info_json],
474
+ outputs = []
475
+ )
476
 
477
+ # step2
478
+ # def update_selection()
479
+ def update_radio(app_state, channel_info, selected):
480
+
481
+ # save info before clicking on next_btn
482
+ if selected != []:
483
+ prev_target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
484
+ prev_target_idx = channel_info["templateByName"][prev_target_name]["index"]
485
+
486
+ selected_idx = channel_info["inputByName"][selected]["index"]
487
+ app_state["stage1NewOrder"][prev_target_idx] = [selected_idx]
488
+
489
+ channel_info["templateByName"][prev_target_name]["matched"] = True
490
+ channel_info["inputByName"][selected]["assigned"] = True
491
+ print(prev_target_name, '<-', selected)
492
+
493
+ # update the current round
494
+ app_state["fillingCount"] += 1
495
+ unassigned = [channel for channel in channel_info["inputByName"]
496
+ if channel_info["inputByName"][channel]["assigned"]==False]
497
+
498
+ target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
499
+
500
+ radio_label = target_name+' ('+str(app_state["fillingCount"])+'/'+str(app_state["totalFillingNum"])+')'
501
+
502
+ if len(unassigned)==1 or app_state["fillingCount"]==app_state["totalFillingNum"]:
503
+ return {app_state_json : app_state,
504
+ channel_info_json : channel_info,
505
+ radio : gr.Radio(choices=unassigned, value=[], label=radio_label),
506
+ step2_btn : gr.Button(visible=False),
507
+ next_btn : gr.Button("Next step", visible=True)}
508
+ else:
509
+ return {app_state_json : app_state,
510
+ channel_info_json : channel_info,
511
+ radio : gr.Radio(choices=unassigned, value=[], label=radio_label)}
512
+
513
+ step2_btn.click(
514
+ fn = update_radio,
515
+ inputs = [app_state_json, channel_info_json, radio],
516
+ outputs = [app_state_json, channel_info_json, radio, step2_btn, next_btn]
517
+
518
  ).success(
519
+ fn = None,
520
+ js = indication_js,
521
+ inputs = [app_state_json, channel_info_json],
522
+ outputs = []
523
+ )
524
+
525
+ # step3
526
+ @fillmode_btn.click(inputs = [app_state_json, channel_info_json, in_fill_mode],
527
+ outputs = [app_state_json, in_fill_mode, fillmode_btn, chkbox_group, step3_btn, run_btn])
528
+ def fill_value(app_state, channel_info, fill_mode):
529
+
530
+ if fill_mode == 'zero':
531
+ app_state["state"] = "finished"
532
+ gr.Info('The mapping process is finished!')
533
+
534
+ return {app_state_json : app_state,
535
+ desc_md : gr.Markdown(visible=False),
536
+ in_fill_mode : gr.Dropdown(visible=False),
537
+ fillmode_btn : gr.Button(visible=False),
538
+ run_btn : gr.Button(interactive=True)}
539
+
540
+ elif fill_mode == 'mean':
541
+ app_state["state"] = "step3-selecting"
542
+ app_state = find_neighbors(app_state, channel_info, fill_mode)
543
+
544
+ name = channel_info["missingChannels"][0]
545
+ idx = channel_info["templateByName"][name]["index"]
546
+ value = app_state["stage1NewOrder"][idx]
547
+ value = [channel_info["inputByIndex"][i] for i in value]
548
+ label = name+' (1/'+str(app_state["totalFillingNum"])+')'
549
+
550
+ return {app_state_json : app_state,
551
+ in_fill_mode : gr.Dropdown(visible=False),
552
+ fillmode_btn : gr.Button(visible=False),
553
+ chkbox_group : gr.CheckboxGroup(choices=channel_info["inputByIndex"],
554
+ value=value, label=label, visible=True),
555
+ step3_btn : gr.Button(visible=True)}
556
+
557
+ def update_chkbox(app_state, channel_info, selected):
558
+
559
+ # save info before clicking on next_btn
560
+ if selected != []:
561
+ prev_target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
562
+ prev_target_idx = channel_info["templateByName"][prev_target_name]["index"]
563
+
564
+ selected_idx = [channel_info["inputByName"][channel]["index"] for channel in selected]
565
+ app_state["stage1NewOrder"][prev_target_idx] = selected_idx
566
+
567
+ #print('Selection for missing channel "{}"({}): {}'.format(prev_target_name, prev_target_idx, selected))
568
 
569
+ # update next round
570
+ app_state["fillingCount"] += 1
571
+
572
+ target_name = channel_info["missingChannels"][app_state["fillingCount"]-1]
573
+ target_idx = channel_info["templateByName"][target_name]["index"]
574
+
575
+ chkbox_value = app_state["stage1NewOrder"][target_idx]
576
+ chkbox_value = [channel_info["inputByIndex"][i] for i in chkbox_value]
577
+ chkbox_label = target_name+' ('+str(app_state["fillingCount"])+'/'+str(app_state["totalFillingNum"])+')'
578
+
579
+ if app_state["fillingCount"] == app_state["totalFillingNum"]:
580
+ return {app_state_json : app_state,
581
+ chkbox_group : gr.CheckboxGroup(value=chkbox_value, label=chkbox_label),
582
+ step3_btn : gr.Button(visible=False),
583
+ next_btn : gr.Button("Submit", visible=True)}
584
+ else:
585
+ return {app_state_json : app_state,
586
+ chkbox_group : gr.CheckboxGroup(value=chkbox_value, label=chkbox_label)}
587
+
588
+ step3_btn.click(
589
+ fn = update_chkbox,
590
+ inputs = [app_state_json, channel_info_json, chkbox_group],
591
+ outputs = [app_state_json, chkbox_group, step3_btn, next_btn]
592
+
593
  ).success(
594
+ fn = None,
595
+ js = indication_js,
596
+ inputs = [app_state_json, channel_info_json],
597
  outputs = []
598
  )
599
 
600
+
601
  def delete_file(filename):
602
  try:
603
  os.remove(filename)
604
  except OSError as e:
605
  print(e)
606
 
607
+ def reset_run(app_state, channel_info, raw_data, model_name):
608
  filepath = app_state["filepath"]
609
  input_name = os.path.basename(str(raw_data))
610
  output_name = os.path.splitext(input_name)[0]+'_'+model_name+'.csv'
611
 
612
+ in_num = len(channel_info["inputByName"])
613
+ matched_num = len([channel for channel in channel_info["inputByName"]
614
+ if channel_info["inputByName"][channel]["matched"]==True])
615
+ batch_num = math.ceil((in_num-matched_num)/30) + 1
616
+
617
  app_state["filenames"]["denoised"] = filepath + output_name
618
  app_state.update({
619
  "runnigState" : "stage1",
620
  "batchCount" : 1,
621
+ "totalBatchNum" : batch_num,
622
  "stage2NewOrder" : [[]]*30
623
  })
624
 
 
645
  app_state, channel_info = mapping_stage2(app_state, channel_info, fill_mode)
646
  if app_state["runnigState"] == "finished":
647
  break
 
648
 
649
  reorder_to_template(app_state, raw_data)
650
  # step1: Data preprocessing
 
660
 
661
  delete_file(filepath+'mapped.csv')
662
  delete_file(filepath+'denoised.csv')
663
+ app_state["batchCount"] += 1
664
 
665
  yield {run_btn : gr.Button(interactive=True),
666
  batch_md : gr.Markdown(visible=False),
667
  out_denoised_data : gr.File(new_filename, visible=True)}
668
 
669
  run_btn.click(
670
+ fn = reset_run,
671
+ inputs = [app_state_json, channel_info_json, in_raw_data, in_model_name],
672
  outputs = [app_state_json, run_btn, batch_md, out_denoised_data]
673
 
674
  ).success(
 
678
  )
679
 
680
  if __name__ == "__main__":
681
+ demo.launch(server_name="0.0.0.0", server_port=7860)
channel_mapping.py CHANGED
@@ -15,8 +15,8 @@ def reorder_to_template(app_state, filename):
15
  old_data = utils.read_train_data(filename) # original raw data
16
  new_data = np.zeros((30, old_data.shape[1])) # reordered raw data
17
  new_filename = app_state["filepath"]+'mapped.csv'
18
- #print('new order 1:', app_state["stage1NewOrder"])
19
- #print('new order 2:', app_state["stage2NewOrder"])
20
 
21
  zero_arr = np.zeros((1, old_data.shape[1]))
22
  old_data = np.concatenate((old_data, zero_arr), axis=0)
@@ -96,7 +96,7 @@ def align_coords(channel_info, template_montage, input_montage):
96
  input_order = channel_info["inputByIndex"]
97
  matched = [channel for channel in input_dict if input_dict[channel]["matched"]==True]
98
 
99
- # 2-d (fot the indication of missing template channel's position when fill_mode:'mean_manual')
100
  fig = [template_montage.plot(), input_montage.plot()]
101
  fig[0].set_size_inches(5.6, 5.6)
102
  fig[1].set_size_inches(5.6, 5.6)
@@ -161,39 +161,33 @@ def align_coords(channel_info, template_montage, input_montage):
161
  })
162
  return channel_info
163
 
164
- def fill_channels(app_state, channel_info, fill_mode):
165
-
166
  new_idx = app_state["stage1NewOrder"] if app_state["runnigState"]=="stage1" else app_state["stage2NewOrder"]
167
  template_dict = channel_info["templateByName"]
168
  input_dict = channel_info["inputByName"]
169
  template_order = channel_info["templateByIndex"]
170
  input_order = channel_info["inputByIndex"]
171
- z_row_idx = channel_info["dataShape"][0]
172
  unmatched = [channel for channel in template_dict if template_dict[channel]["matched"]==False]
173
  if unmatched == []:
174
- return app_state
175
 
176
- if fill_mode == 'zero':
177
- for channel in unmatched:
178
- idx = template_dict[channel]["index"]
179
- new_idx[idx] = [z_row_idx]
180
 
181
- elif fill_mode == 'mean_auto':
182
- # use KNN to choose k nearest channels
183
- in_coords = [input_dict[channel]["coord"] for channel in input_order]
184
- in_coords = np.array([in_coords[i] for i in range(len(in_coords))])
185
-
186
- k = 4 if len(input_dict)>4 else len(input_dict)
187
- knn = NearestNeighbors(n_neighbors=k, metric='euclidean')
188
- knn.fit(in_coords)
 
 
 
 
189
 
190
- for channel in unmatched:
191
- distances, indices = knn.kneighbors(np.array(template_dict[channel]["coord"]).reshape(1,-1))
192
- selected = [input_order[i] for i in indices[0]]
193
- print(channel, ':', selected)
194
-
195
- idx = template_dict[channel]["index"]
196
- new_idx[idx] = indices[0].tolist()
197
 
198
  if app_state["runnigState"] == "stage1":
199
  app_state["stage1NewOrder"] = new_idx
@@ -202,7 +196,8 @@ def fill_channels(app_state, channel_info, fill_mode):
202
 
203
  return app_state
204
 
205
- def mapping_stage1(app_state, channel_info, data_file, loc_file, fill_mode):
 
206
  second1 = time.time()
207
 
208
  template_montage, input_montage, template_dict, input_dict = read_montage_data(loc_file)
@@ -233,10 +228,10 @@ def mapping_stage1(app_state, channel_info, data_file, loc_file, fill_mode):
233
  input_dict[channel].matched = True
234
  input_dict[channel].assigned = True
235
  else:
236
- missing_channels.append(i)
237
 
238
  channel_info.update({
239
- "missingChannelsIndex" : missing_channels,
240
  "templateByName" : {k : v.__dict__ for k,v in template_dict.items()},
241
  "inputByName" : {k : v.__dict__ for k,v in input_dict.items()},
242
  "templateByIndex" : template_montage.ch_names,
@@ -250,11 +245,11 @@ def mapping_stage1(app_state, channel_info, data_file, loc_file, fill_mode):
250
  # align input, template's coordinates
251
  channel_info = align_coords(channel_info, template_montage, input_montage)
252
  # fill the unmatched channels
253
- app_state = fill_channels(app_state, channel_info, fill_mode)
254
 
255
  second2 = time.time()
256
  print('Mapping (stage1) finished in',second2 - second1,'s.')
257
- return app_state, channel_info
258
 
259
  def mapping_stage2(app_state, channel_info, fill_mode):
260
  second1 = time.time()
@@ -311,7 +306,7 @@ def mapping_stage2(app_state, channel_info, fill_mode):
311
  })
312
 
313
  # fill the unmatched channels
314
- app_state = fill_channels(app_state, channel_info, fill_mode)
315
 
316
  second2 = time.time()
317
  print(f'Mapping (stage2-{app_state["batchCount"]-1}) finished in {second2 - second1}s.')
 
15
  old_data = utils.read_train_data(filename) # original raw data
16
  new_data = np.zeros((30, old_data.shape[1])) # reordered raw data
17
  new_filename = app_state["filepath"]+'mapped.csv'
18
+ print('new order 1:', app_state["stage1NewOrder"])
19
+ print('new order 2:', app_state["stage2NewOrder"])
20
 
21
  zero_arr = np.zeros((1, old_data.shape[1]))
22
  old_data = np.concatenate((old_data, zero_arr), axis=0)
 
96
  input_order = channel_info["inputByIndex"]
97
  matched = [channel for channel in input_dict if input_dict[channel]["matched"]==True]
98
 
99
+ # 2-d (for the indication of missing template channel's position when fill_mode:'mean_manual')
100
  fig = [template_montage.plot(), input_montage.plot()]
101
  fig[0].set_size_inches(5.6, 5.6)
102
  fig[1].set_size_inches(5.6, 5.6)
 
161
  })
162
  return channel_info
163
 
164
+ def find_neighbors(app_state, channel_info, fill_mode):
 
165
  new_idx = app_state["stage1NewOrder"] if app_state["runnigState"]=="stage1" else app_state["stage2NewOrder"]
166
  template_dict = channel_info["templateByName"]
167
  input_dict = channel_info["inputByName"]
168
  template_order = channel_info["templateByIndex"]
169
  input_order = channel_info["inputByIndex"]
170
+ #z_row_idx = channel_info["dataShape"][0]
171
  unmatched = [channel for channel in template_dict if template_dict[channel]["matched"]==False]
172
  if unmatched == []:
173
+ return app_state # change mothing
174
 
 
 
 
 
175
 
176
+ in_coords = [input_dict[channel]["coord"] for channel in input_order]
177
+ in_coords = np.array([in_coords[i] for i in range(len(in_coords))])
178
+
179
+ # use KNN to choose k nearest channels
180
+ k = 4 if len(input_dict)>4 else len(input_dict)
181
+ knn = NearestNeighbors(n_neighbors=k, metric='euclidean')
182
+ knn.fit(in_coords)
183
+
184
+ for channel in unmatched:
185
+ distances, indices = knn.kneighbors(np.array(template_dict[channel]["coord"]).reshape(1,-1))
186
+ selected = [input_order[i] for i in indices[0]]
187
+ print(channel, ':', selected)
188
 
189
+ idx = template_dict[channel]["index"]
190
+ new_idx[idx] = indices[0].tolist()
 
 
 
 
 
191
 
192
  if app_state["runnigState"] == "stage1":
193
  app_state["stage1NewOrder"] = new_idx
 
196
 
197
  return app_state
198
 
199
+ def mapping_stage1(app_state, channel_info, loc_file):
200
+ yield app_state, channel_info, gr.Markdown("Mapping...", visible=True) # app_state, channel_info???
201
  second1 = time.time()
202
 
203
  template_montage, input_montage, template_dict, input_dict = read_montage_data(loc_file)
 
228
  input_dict[channel].matched = True
229
  input_dict[channel].assigned = True
230
  else:
231
+ missing_channels.append(channel)
232
 
233
  channel_info.update({
234
+ "missingChannels" : missing_channels,
235
  "templateByName" : {k : v.__dict__ for k,v in template_dict.items()},
236
  "inputByName" : {k : v.__dict__ for k,v in input_dict.items()},
237
  "templateByIndex" : template_montage.ch_names,
 
245
  # align input, template's coordinates
246
  channel_info = align_coords(channel_info, template_montage, input_montage)
247
  # fill the unmatched channels
248
+ #app_state = fill_channels(app_state, channel_info, fill_mode)
249
 
250
  second2 = time.time()
251
  print('Mapping (stage1) finished in',second2 - second1,'s.')
252
+ yield app_state, channel_info, gr.Markdown("", visible=False)
253
 
254
  def mapping_stage2(app_state, channel_info, fill_mode):
255
  second1 = time.time()
 
306
  })
307
 
308
  # fill the unmatched channels
309
+ app_state = find_neighbors(app_state, channel_info, fill_mode)
310
 
311
  second2 = time.time()
312
  print(f'Mapping (stage2-{app_state["batchCount"]-1}) finished in {second2 - second1}s.')