audrey06100 commited on
Commit
84cd80a
·
1 Parent(s): d796428
Files changed (2) hide show
  1. app.py +107 -120
  2. app_utils.py +68 -42
app.py CHANGED
@@ -22,14 +22,14 @@ The following steps will guide you through the process of mapping your EEG chann
22
 
23
  ### Step1: Initial Matching and Scaling
24
  After clicking on ``Map`` button, we will first match your channels to our template channels by their names. Using the matched channels as reference points, we will apply Thin Plate Spline (TPS) transformation to scale your montage to align with our template's dimensions. The template montage and your scaled montage will be displayed side by side for comparison. Channels that do not have a match in our template will be **highlighted in red**.
25
- - If your data includes all the 30 template channels, you will be directed to **Mapping Results**.
26
  - If your data doesn't include all the 30 template channels and you have some channels that do not match the template, you will be directed to **Step2**.
27
  - If all your channels are included in our template but you have fewer than 30 channels, you will be directed to **Step3**.
28
 
29
  ### Step2: Forwarding Unmatched Channels
30
  In this step, you will handle the channels that didn't have a direct match with our template, by manually assigning them to the template channels that are still empty, ensuring the most efficient use of your data.
31
  Your unmatched channels, previously highlighted in red, will be shown on your montage with a radio button displayed above each. You can choose to forward the data from these unmatched channels to the empty template channels. The interface will display each empty template channel in sequence, allowing you to select which of your unmatched channels to forward.
32
- - If all empty template channels are filled by your selections, you will be directed to **Mapping Results**.
33
  - If there are still empty template channels remaining, you will be directed to **Step3**.
34
 
35
  ### Step3: Filling Remaining Template Channels
@@ -37,15 +37,15 @@ To run the models successfully, we need to ensure that all 30 template channels
37
  - **Mean** method: Each empty template channel is filled with the average value of data from the nearest input channels. By default, the 4 closest input channels (determined after aligning your montage to the template's scale using TPS) are selected for this averaging process. On the interface, you will see checkboxes displayed above each of your channel. The 4 nearest channels are pre-selected by default for each empty template channels, but you can modify these selections as needed. If you uncheck all the checkboxes for a particular template channel, it will be filled with zeros.
38
  - **Zero** method: All empty template channels are filled with zeros.
39
  Choose the method that best suits your needs, considering that the model's performance may vary depending on the method used.
40
- Once all template channels are filled, you will be directed to **Mapping Results**.
41
 
42
- ### Mapping Results
43
  After completing the previous steps, your channels will be aligned with the template channels required by our models.
44
- - In case there are still some channels that haven't been mapped, we will automatically batch and optimally assign them to the template. This ensures that even channels not initially mapped will still be included in the final results.
45
- - Once the mapping process is completed, a JSON file containing the mapping results will be generated. This file is necessary only if you plan to run the models using the <a href="">source code</a>; otherwise, you can ignore it.
46
 
47
  ## 2. Decode data
48
- After clicking on ``Run`` button, we will process your EEG data based on the mapping results. If necessary, your data will be divided into batches and run the models on each batch sequentially, ensuring that all channels are properly processed.
49
  """
50
 
51
  icunet = """
@@ -75,8 +75,6 @@ init_js = """
75
  position: relative;
76
  width: 100%;
77
  aspect-ratio: 1;
78
- //width: 560px;
79
- //height: 560px;
80
  background: url("file=${stage1_info.fileNames.inputMontage}");
81
  background-size: contain;
82
  `;
@@ -213,8 +211,8 @@ update_js = """
213
 
214
  with gr.Blocks() as demo:
215
  stage1_json = gr.JSON({}, visible=False)
216
- stage2_json = gr.JSON(visible=False)
217
- channel_json = gr.JSON(visible=False)
218
 
219
  gr.Markdown(intro)
220
  with gr.Row():
@@ -232,7 +230,7 @@ with gr.Blocks() as demo:
232
  # step1
233
  with gr.Row():
234
  tpl_img = gr.Image("./template_montage.png", label="Template montage", visible=False)
235
- mapped_img = gr.Image(label="Matching results", visible=False)
236
  # step2
237
  radio_group = gr.Radio(elem_id="radio-group", visible=False)
238
  # step3
@@ -295,7 +293,7 @@ with gr.Blocks() as demo:
295
  return {stage1_json : stage1_info}
296
 
297
  # stop Stage2
298
- if stage2_info!=None and stage2_info["state"]=="running":
299
  utils.dataDelete(stage2_info["filePath"])
300
 
301
  rootpath = os.path.dirname(str(in_loc))
@@ -331,7 +329,7 @@ with gr.Blocks() as demo:
331
  "unassignedInputs" : None,
332
  "emptyTemplates" : None,
333
  "batchNum" : None,
334
- "mappingResults" : [
335
  {
336
  "newOrder" : None,
337
  "isOriginalData" : None
@@ -339,25 +337,25 @@ with gr.Blocks() as demo:
339
  }
340
  ]
341
  }
342
- stage2_info = None
343
- channel_info = None
344
  return {stage1_json : stage1_info,
345
  stage2_json : stage2_info,
346
  channel_json : channel_info,
347
  # --------------------Stage1-------------------------
348
  map_btn : gr.Button(interactive=False),
349
- desc_md : gr.Markdown("", visible=False),
350
- next_btn : gr.Button(visible=False),
351
  tpl_img : gr.Image(visible=False),
352
  mapped_img : gr.Image(value=None, visible=False),
353
  radio_group : gr.Radio(choices=[], value=[], label="", visible=False),
354
- clear_btn : gr.Button(visible=False),
355
- step2_btn : gr.Button(visible=False),
356
  in_fillmode : gr.Dropdown(value="mean", visible=False),
357
  fillmode_btn : gr.Button(visible=False),
358
  chkbox_group : gr.CheckboxGroup(choices=[], value=[], label='', visible=False),
 
 
359
  step3_btn : gr.Button(visible=False),
360
- out_result_file : gr.File(value=None, visible=False),
361
  # --------------------Stage2-------------------------
362
  in_data_file : gr.File(value=None),
363
  in_samplerate : gr.Textbox(value=None),
@@ -373,13 +371,11 @@ with gr.Blocks() as demo:
373
  def init_next_step(stage1_info, channel_info, fillmode, sel_radio, sel_chkbox):
374
  if stage1_info["errorFlag"] == True:
375
  stage1_info["errorFlag"] = False
376
- yield {stage1_json : stage1_info}
377
 
378
  # ========================================step0=========================================
379
  # step0 to step1
380
- elif stage1_info["state"] == "step1-initializing":
381
- yield {desc_md : gr.Markdown("Mapping...", visible=True)}
382
-
383
  # match the names
384
  stage1_info, channel_info, tpl_montage, in_montage = app_utils.match_names(stage1_info)
385
  # scale the coordinates
@@ -402,7 +398,7 @@ with gr.Blocks() as demo:
402
  - channels highlighted in red are those that do not match any template channels.
403
  """
404
  stage1_info["state"] = "step1-finished"
405
- yield {stage1_json : stage1_info,
406
  channel_json : channel_info,
407
  map_btn : gr.Button(interactive=True),
408
  desc_md : gr.Markdown(md),
@@ -418,22 +414,23 @@ with gr.Blocks() as demo:
418
  # step1 to step4
419
  if matched_num == 30:
420
  md = """
421
- ### Mapping Results
422
  The mapping process has been finished.
423
  Download the file below if you plan to run the models using the <a href="">source code</a>.
424
  """
425
- # finalize and save the mapping results
426
  outputname = stage1_info["fileNames"]["outputResult"]
427
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
428
 
429
  stage1_info["state"] = "finished"
430
- yield {stage1_json : stage1_info,
431
  channel_json : channel_info,
432
  desc_md : gr.Markdown(md),
 
433
  tpl_img : gr.Image(visible=False),
434
  mapped_img : gr.Image(visible=False),
435
  next_btn : gr.Button(visible=False),
436
- out_result_file : gr.File(outputname, visible=True)}
437
  # step1 to step2
438
  elif in_num > matched_num:
439
  md = """
@@ -452,14 +449,14 @@ with gr.Blocks() as demo:
452
  stage1_info["state"] = "step2-selecting"
453
  # determine which button to display
454
  if stage1_info["step2"]["totalNum"] == 1:
455
- yield {stage1_json : stage1_info,
456
  desc_md : gr.Markdown(md),
457
  tpl_img : gr.Image(visible=False),
458
  mapped_img : gr.Image(visible=False),
459
  radio_group : gr.Radio(choices=stage1_info["unassignedInputs"], value=[], label=label, visible=True),
460
  clear_btn : gr.Button(visible=True)}
461
  else:
462
- yield {stage1_json : stage1_info,
463
  desc_md : gr.Markdown(md),
464
  tpl_img : gr.Image(visible=False),
465
  mapped_img : gr.Image(visible=False),
@@ -474,7 +471,7 @@ with gr.Blocks() as demo:
474
  Select one of the methods provided below to fill the remaining template channels.
475
  """
476
  stage1_info["state"] = "step3-select-method"
477
- yield {stage1_json : stage1_info,
478
  desc_md : gr.Markdown(md),
479
  tpl_img : gr.Image(visible=False),
480
  mapped_img : gr.Image(visible=False),
@@ -491,8 +488,8 @@ with gr.Blocks() as demo:
491
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
492
  sel_idx = channel_info["inputDict"][sel_radio]["index"]
493
 
494
- stage1_info["mappingResults"][0]["newOrder"][prev_tpl_idx] = [sel_idx]
495
- stage1_info["mappingResults"][0]["isOriginalData"][prev_tpl_idx] = True
496
  channel_info["templateDict"][prev_tpl_name]["matched"] = True
497
  channel_info["inputDict"][sel_radio]["assigned"] = True
498
  #print(prev_tpl_name, '<-', sel_radio)
@@ -508,7 +505,7 @@ with gr.Blocks() as demo:
508
  # step2 to step4
509
  if len(stage1_info["emptyTemplates"]) == 0:
510
  md = """
511
- ### Mapping Results
512
  The mapping process has been finished.
513
  Download the file below if you plan to run the models using the <a href="">source code</a>.
514
  """
@@ -516,13 +513,14 @@ with gr.Blocks() as demo:
516
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
517
 
518
  stage1_info["state"] = "finished"
519
- yield {stage1_json : stage1_info,
520
  channel_json : channel_info,
521
  desc_md : gr.Markdown(md),
522
- radio_group : gr.Radio(visible=False),
523
  out_result_file : gr.File(outputname, visible=True),
 
524
  clear_btn : gr.Button(visible=False),
525
- next_btn : gr.Button(visible=False)}
 
526
  # step2 to step3-1
527
  else:
528
  md = """
@@ -530,7 +528,7 @@ with gr.Blocks() as demo:
530
  Select one of the methods provided below to fill the remaining template channels.
531
  """
532
  stage1_info["state"] = "step3-select-method"
533
- yield {stage1_json : stage1_info,
534
  channel_json : channel_info,
535
  desc_md : gr.Markdown(md),
536
  radio_group : gr.Radio(visible=False),
@@ -544,7 +542,7 @@ with gr.Blocks() as demo:
544
  # step3-1 to step4
545
  if fillmode == "zero":
546
  md = """
547
- ### Mapping Results
548
  The mapping process has been finished.
549
  Download the file below if you plan to run the models using the <a href="">source code</a>.
550
  """
@@ -552,12 +550,13 @@ with gr.Blocks() as demo:
552
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
553
 
554
  stage1_info["state"] = "finished"
555
- yield {stage1_json : stage1_info,
556
  channel_json : channel_info,
557
  desc_md : gr.Markdown(md),
 
558
  in_fillmode : gr.Dropdown(visible=False),
559
  fillmode_btn : gr.Button(visible=False),
560
- out_result_file : gr.File(outputname, visible=True)}
561
  # step3-1 to step3-2
562
  elif fillmode == "mean":
563
  md = """
@@ -566,10 +565,10 @@ with gr.Blocks() as demo:
566
  value of the data from the selected channels. (By default, the 4 nearest channels are pre-selected.)
567
  """
568
  # find the 4 nearest in_channels for each unmatched tpl_channels
569
- stage1_info["mappingResults"][0]["newOrder"] = app_utils.find_neighbors(
570
  channel_info,
571
  stage1_info["emptyTemplates"],
572
- stage1_info["mappingResults"][0]["newOrder"])
573
  # initialize the progress indication label
574
  stage1_info["step3"] = {
575
  "count" : 1,
@@ -579,13 +578,13 @@ with gr.Blocks() as demo:
579
  label = '{} (1/{})'.format(tpl_name, stage1_info["step3"]["totalNum"])
580
 
581
  tpl_idx = channel_info["templateDict"][tpl_name]["index"]
582
- value = stage1_info["mappingResults"][0]["newOrder"][tpl_idx]
583
  value = [channel_info["inputNames"][i] for i in value]
584
 
585
  stage1_info["state"] = "step3-2-selecting"
586
  # determine which button to display
587
  if stage1_info["step3"]["totalNum"] == 1:
588
- yield {stage1_json : stage1_info,
589
  desc_md : gr.Markdown(md),
590
  in_fillmode : gr.Dropdown(visible=False),
591
  fillmode_btn : gr.Button(visible=False),
@@ -593,7 +592,7 @@ with gr.Blocks() as demo:
593
  value=value, label=label, visible=True),
594
  next_btn : gr.Button(visible=True)}
595
  else:
596
- yield {stage1_json : stage1_info,
597
  desc_md : gr.Markdown(md),
598
  in_fillmode : gr.Dropdown(visible=False),
599
  fillmode_btn : gr.Button(visible=False),
@@ -608,11 +607,11 @@ with gr.Blocks() as demo:
608
  prev_tpl_name = stage1_info["emptyTemplates"][stage1_info["step3"]["count"]-1]
609
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
610
  sel_idx = [channel_info["inputDict"][name]["index"] for name in sel_chkbox]
611
- stage1_info["mappingResults"][0]["newOrder"][prev_tpl_idx] = sel_idx if sel_idx!=[] else [None]
612
  #print(prev_tpl_name, '<-', sel_chkbox)
613
  # ----------------------------------------------------------------------------------
614
  md = """
615
- ### Mapping Results
616
  The mapping process has been finished.
617
  Download the file below if you plan to run the models using the <a href="">source code</a>.
618
  """
@@ -620,18 +619,19 @@ with gr.Blocks() as demo:
620
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
621
 
622
  stage1_info["state"] = "finished"
623
- yield {stage1_json : stage1_info,
624
  channel_json : channel_info,
625
  desc_md : gr.Markdown(md),
 
626
  chkbox_group : gr.CheckboxGroup(visible=False),
627
  next_btn : gr.Button(visible=False),
628
- out_result_file : gr.File(outputname, visible=True)}
629
 
630
  next_btn.click(
631
  fn = init_next_step,
632
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
633
- outputs = [stage1_json, channel_json, desc_md, tpl_img, mapped_img, radio_group, clear_btn, step2_btn,
634
- in_fillmode, fillmode_btn, chkbox_group, step3_btn, out_result_file, next_btn]
635
  ).success(
636
  fn = None,
637
  js = init_js,
@@ -646,9 +646,9 @@ with gr.Blocks() as demo:
646
  map_btn.click(
647
  fn = reset_all,
648
  inputs = [stage1_json, stage2_json, in_loc_file],
649
- outputs = [stage1_json, stage2_json, channel_json, map_btn, desc_md, next_btn, tpl_img, mapped_img,
650
- radio_group, clear_btn, step2_btn, in_fillmode, fillmode_btn, chkbox_group, step3_btn,
651
- out_result_file, in_data_file, in_samplerate, run_btn, cancel_btn, batch_md, out_data_file]
652
  ).success(
653
  fn = init_next_step,
654
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
@@ -686,8 +686,8 @@ with gr.Blocks() as demo:
686
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
687
  sel_idx = channel_info["inputDict"][sel_name]["index"]
688
 
689
- stage1_info["mappingResults"][0]["newOrder"][prev_tpl_idx] = [sel_idx]
690
- stage1_info["mappingResults"][0]["isOriginalData"][prev_tpl_idx] = True
691
  channel_info["templateDict"][prev_tpl_name]["matched"] = True
692
  channel_info["inputDict"][sel_name]["assigned"] = True
693
  #print(prev_tpl_name, '<-', sel_name)
@@ -736,7 +736,7 @@ with gr.Blocks() as demo:
736
  prev_tpl_name = stage1_info["emptyTemplates"][step3["count"]-1]
737
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
738
  sel_idx = [channel_info["inputDict"][name]["index"] for name in sel_name]
739
- stage1_info["mappingResults"][0]["newOrder"][prev_tpl_idx] = sel_idx if sel_idx!=[] else [None]
740
  #print(prev_tpl_name, '<-', sel_name)
741
 
742
  # ---------------------------------update the new round---------------------------------
@@ -746,7 +746,7 @@ with gr.Blocks() as demo:
746
  label = '{} ({}/{})'.format(tpl_name, step3["count"], step3["totalNum"])
747
 
748
  tpl_idx = channel_info["templateDict"][tpl_name]["index"]
749
- value = stage1_info["mappingResults"][0]["newOrder"][tpl_idx]
750
  value = [channel_info["inputNames"][i] for i in value]
751
 
752
  stage1_info["step3"] = step3
@@ -763,8 +763,8 @@ with gr.Blocks() as demo:
763
  fillmode_btn.click(
764
  fn = init_next_step,
765
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
766
- outputs = [stage1_json, channel_json, desc_md, in_fillmode, fillmode_btn, chkbox_group, step3_btn,
767
- out_result_file, next_btn]
768
  ).success(
769
  fn = None,
770
  js = init_js,
@@ -786,22 +786,19 @@ with gr.Blocks() as demo:
786
 
787
  # +========================================================================================+
788
  # | Stage2: decode data |
789
- # +========================================================================================+
790
- @gr.on(triggers = [in_data_file.upload, in_data_file.clear, in_samplerate.input, out_result_file.change],
791
- inputs = [stage1_json, in_data_file, in_samplerate], outputs = run_btn)
792
- def check_input(stage1_info, in_data, samplerate):
793
- if stage1_info["state"]=="finished" and in_data!=None and samplerate!="":
794
- return gr.Button(interactive=True)
795
- else:
796
- return gr.Button(interactive=False)
797
-
798
  @cancel_btn.click(inputs = stage2_json, outputs = [stage2_json, cancel_btn, batch_md])
799
  def stop_stage2(stage2_info):
800
  utils.dataDelete(stage2_info["filePath"])
801
  stage2_info["state"] = "stopped"
802
  return stage2_info, gr.Button(interactive=False), gr.Markdown(visible=False)
803
 
804
- def reset_stage2(in_data, samplerate, modelname):
 
 
 
 
 
805
  rootpath = os.path.dirname(str(in_data))
806
  # delete the previous folder(s) of Stage2
807
  folders = [ f.path for f in os.scandir(rootpath) if f.is_dir()]
@@ -821,7 +818,7 @@ with gr.Blocks() as demo:
821
  "outputData" : rootpath+'/'+stage2_id+'/'+outputname
822
  },
823
  "state" : "running",
824
- "sampleRate" : int(samplerate)
825
  }
826
  return {stage2_json : stage2_info,
827
  run_btn : gr.Button(visible=False),
@@ -829,61 +826,51 @@ with gr.Blocks() as demo:
829
  batch_md : gr.Markdown("", visible=True),
830
  out_data_file : gr.File(value=None, visible=False)}
831
 
832
- def run_model(stage1_info, stage2_info, modelname):
833
- batch_num = stage1_info["batchNum"]
834
- mapping_results = stage1_info["mappingResults"]
835
- samplerate = stage2_info["sampleRate"]
836
- filepath = stage2_info["filePath"]
837
- inputname = stage2_info["fileNames"]["inputData"]
838
- outputname = stage2_info["fileNames"]["outputData"]
839
 
840
- out_basename = os.path.basename(str(outputname))
841
- out_basename = os.path.splitext(out_basename)[0]
842
- break_flag = False
843
- for i in range(batch_num):
844
- yield {batch_md : gr.Markdown('Running model({}/{})...'.format(i+1, batch_num))}
845
 
846
- new_idx = mapping_results[i]["newOrder"]
847
- orig_flags = mapping_results[i]["isOriginalData"]
848
- m_filename = 'mapped_{:02d}.csv'.format(i+1)
849
- d_filename = '{}_{:02d}.csv'.format(out_basename, i+1)
850
- try:
851
- # establish a temp folder
852
- os.mkdir(filepath+'temp_data/')
853
 
854
- # step1: Reorder input data
855
- data_shape = app_utils.reorder_data(new_idx, orig_flags, inputname, filepath+'temp_data/'+m_filename)
856
- # step2: Data preprocessing
857
- total_file_num = utils.preprocessing(filepath+'temp_data/', m_filename, samplerate)
858
- # step3: Signal reconstruction
859
- utils.reconstruct(modelname, total_file_num, filepath+'temp_data/', d_filename, samplerate)
860
- # step4: Restore original order
861
- app_utils.restore_order(i, data_shape, new_idx, orig_flags, filepath+'temp_data/'+d_filename, outputname)
862
- except FileNotFoundError:
863
- print('break!!')
864
- break_flag = True
865
- break
 
 
 
 
866
  else:
867
- utils.dataDelete(filepath+'temp_data/')
868
-
869
- if break_flag == True:
870
- yield {run_btn : gr.Button(visible=True),
871
- cancel_btn : gr.Button(visible=False)}
872
- else:
873
- stage2_info["state"] = "finished"
874
- yield {stage2_json : stage2_info,
875
- run_btn : gr.Button(visible=True),
876
- cancel_btn : gr.Button(visible=False),
877
- batch_md : gr.Markdown(visible=False),
878
- out_data_file : gr.File(outputname, visible=True)}
879
 
880
  run_btn.click(
881
  fn = reset_stage2,
882
- inputs = [in_data_file, in_samplerate, in_modelname],
883
  outputs = [stage2_json, run_btn, cancel_btn, batch_md, out_data_file]
884
  ).success(
885
- fn = run_model,
886
- inputs = [stage1_json, stage2_json, in_modelname],
887
  outputs = [stage2_json, run_btn, cancel_btn, batch_md, out_data_file]
888
  )
889
 
 
22
 
23
  ### Step1: Initial Matching and Scaling
24
  After clicking on ``Map`` button, we will first match your channels to our template channels by their names. Using the matched channels as reference points, we will apply Thin Plate Spline (TPS) transformation to scale your montage to align with our template's dimensions. The template montage and your scaled montage will be displayed side by side for comparison. Channels that do not have a match in our template will be **highlighted in red**.
25
+ - If your data includes all the 30 template channels, you will be directed to **Mapping Result**.
26
  - If your data doesn't include all the 30 template channels and you have some channels that do not match the template, you will be directed to **Step2**.
27
  - If all your channels are included in our template but you have fewer than 30 channels, you will be directed to **Step3**.
28
 
29
  ### Step2: Forwarding Unmatched Channels
30
  In this step, you will handle the channels that didn't have a direct match with our template, by manually assigning them to the template channels that are still empty, ensuring the most efficient use of your data.
31
  Your unmatched channels, previously highlighted in red, will be shown on your montage with a radio button displayed above each. You can choose to forward the data from these unmatched channels to the empty template channels. The interface will display each empty template channel in sequence, allowing you to select which of your unmatched channels to forward.
32
+ - If all empty template channels are filled by your selections, you will be directed to **Mapping Result**.
33
  - If there are still empty template channels remaining, you will be directed to **Step3**.
34
 
35
  ### Step3: Filling Remaining Template Channels
 
37
  - **Mean** method: Each empty template channel is filled with the average value of data from the nearest input channels. By default, the 4 closest input channels (determined after aligning your montage to the template's scale using TPS) are selected for this averaging process. On the interface, you will see checkboxes displayed above each of your channel. The 4 nearest channels are pre-selected by default for each empty template channels, but you can modify these selections as needed. If you uncheck all the checkboxes for a particular template channel, it will be filled with zeros.
38
  - **Zero** method: All empty template channels are filled with zeros.
39
  Choose the method that best suits your needs, considering that the model's performance may vary depending on the method used.
40
+ Once all template channels are filled, you will be directed to **Mapping Result**.
41
 
42
+ ### Mapping Result
43
  After completing the previous steps, your channels will be aligned with the template channels required by our models.
44
+ - In case there are still some channels that haven't been mapped, we will automatically batch and optimally assign them to the template. This ensures that even channels not initially mapped will still be included in the final result.
45
+ - Once the mapping process is completed, a JSON file containing the mapping result will be generated. This file is necessary only if you plan to run the models using the <a href="">source code</a>; otherwise, you can ignore it.
46
 
47
  ## 2. Decode data
48
+ After clicking on ``Run`` button, we will process your EEG data based on the mapping result. If necessary, your data will be divided into batches and run the models on each batch sequentially, ensuring that all channels are properly processed.
49
  """
50
 
51
  icunet = """
 
75
  position: relative;
76
  width: 100%;
77
  aspect-ratio: 1;
 
 
78
  background: url("file=${stage1_info.fileNames.inputMontage}");
79
  background-size: contain;
80
  `;
 
211
 
212
  with gr.Blocks() as demo:
213
  stage1_json = gr.JSON({}, visible=False)
214
+ stage2_json = gr.JSON({}, visible=False)
215
+ channel_json = gr.JSON({}, visible=False)
216
 
217
  gr.Markdown(intro)
218
  with gr.Row():
 
230
  # step1
231
  with gr.Row():
232
  tpl_img = gr.Image("./template_montage.png", label="Template montage", visible=False)
233
+ mapped_img = gr.Image(label="Matching result", visible=False)
234
  # step2
235
  radio_group = gr.Radio(elem_id="radio-group", visible=False)
236
  # step3
 
293
  return {stage1_json : stage1_info}
294
 
295
  # stop Stage2
296
+ if "state" in stage2_info and stage2_info["state"]=="running":
297
  utils.dataDelete(stage2_info["filePath"])
298
 
299
  rootpath = os.path.dirname(str(in_loc))
 
329
  "unassignedInputs" : None,
330
  "emptyTemplates" : None,
331
  "batchNum" : None,
332
+ "mappingResult" : [
333
  {
334
  "newOrder" : None,
335
  "isOriginalData" : None
 
337
  }
338
  ]
339
  }
340
+ stage2_info = {}
341
+ channel_info = {}
342
  return {stage1_json : stage1_info,
343
  stage2_json : stage2_info,
344
  channel_json : channel_info,
345
  # --------------------Stage1-------------------------
346
  map_btn : gr.Button(interactive=False),
347
+ desc_md : gr.Markdown("", visible=True),
348
+ out_result_file : gr.File(value=None, visible=False),
349
  tpl_img : gr.Image(visible=False),
350
  mapped_img : gr.Image(value=None, visible=False),
351
  radio_group : gr.Radio(choices=[], value=[], label="", visible=False),
 
 
352
  in_fillmode : gr.Dropdown(value="mean", visible=False),
353
  fillmode_btn : gr.Button(visible=False),
354
  chkbox_group : gr.CheckboxGroup(choices=[], value=[], label='', visible=False),
355
+ clear_btn : gr.Button(visible=False),
356
+ step2_btn : gr.Button(visible=False),
357
  step3_btn : gr.Button(visible=False),
358
+ next_btn : gr.Button(visible=False),
359
  # --------------------Stage2-------------------------
360
  in_data_file : gr.File(value=None),
361
  in_samplerate : gr.Textbox(value=None),
 
371
  def init_next_step(stage1_info, channel_info, fillmode, sel_radio, sel_chkbox):
372
  if stage1_info["errorFlag"] == True:
373
  stage1_info["errorFlag"] = False
374
+ return {stage1_json : stage1_info}
375
 
376
  # ========================================step0=========================================
377
  # step0 to step1
378
+ if stage1_info["state"] == "step1-initializing":
 
 
379
  # match the names
380
  stage1_info, channel_info, tpl_montage, in_montage = app_utils.match_names(stage1_info)
381
  # scale the coordinates
 
398
  - channels highlighted in red are those that do not match any template channels.
399
  """
400
  stage1_info["state"] = "step1-finished"
401
+ return {stage1_json : stage1_info,
402
  channel_json : channel_info,
403
  map_btn : gr.Button(interactive=True),
404
  desc_md : gr.Markdown(md),
 
414
  # step1 to step4
415
  if matched_num == 30:
416
  md = """
417
+ ### Mapping Result
418
  The mapping process has been finished.
419
  Download the file below if you plan to run the models using the <a href="">source code</a>.
420
  """
421
+ # finalize and save the mapping result
422
  outputname = stage1_info["fileNames"]["outputResult"]
423
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
424
 
425
  stage1_info["state"] = "finished"
426
+ return {stage1_json : stage1_info,
427
  channel_json : channel_info,
428
  desc_md : gr.Markdown(md),
429
+ out_result_file : gr.File(outputname, visible=True),
430
  tpl_img : gr.Image(visible=False),
431
  mapped_img : gr.Image(visible=False),
432
  next_btn : gr.Button(visible=False),
433
+ run_btn : gr.Button(interactive=True)}
434
  # step1 to step2
435
  elif in_num > matched_num:
436
  md = """
 
449
  stage1_info["state"] = "step2-selecting"
450
  # determine which button to display
451
  if stage1_info["step2"]["totalNum"] == 1:
452
+ return {stage1_json : stage1_info,
453
  desc_md : gr.Markdown(md),
454
  tpl_img : gr.Image(visible=False),
455
  mapped_img : gr.Image(visible=False),
456
  radio_group : gr.Radio(choices=stage1_info["unassignedInputs"], value=[], label=label, visible=True),
457
  clear_btn : gr.Button(visible=True)}
458
  else:
459
+ return {stage1_json : stage1_info,
460
  desc_md : gr.Markdown(md),
461
  tpl_img : gr.Image(visible=False),
462
  mapped_img : gr.Image(visible=False),
 
471
  Select one of the methods provided below to fill the remaining template channels.
472
  """
473
  stage1_info["state"] = "step3-select-method"
474
+ return {stage1_json : stage1_info,
475
  desc_md : gr.Markdown(md),
476
  tpl_img : gr.Image(visible=False),
477
  mapped_img : gr.Image(visible=False),
 
488
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
489
  sel_idx = channel_info["inputDict"][sel_radio]["index"]
490
 
491
+ stage1_info["mappingResult"][0]["newOrder"][prev_tpl_idx] = [sel_idx]
492
+ stage1_info["mappingResult"][0]["isOriginalData"][prev_tpl_idx] = True
493
  channel_info["templateDict"][prev_tpl_name]["matched"] = True
494
  channel_info["inputDict"][sel_radio]["assigned"] = True
495
  #print(prev_tpl_name, '<-', sel_radio)
 
505
  # step2 to step4
506
  if len(stage1_info["emptyTemplates"]) == 0:
507
  md = """
508
+ ### Mapping Result
509
  The mapping process has been finished.
510
  Download the file below if you plan to run the models using the <a href="">source code</a>.
511
  """
 
513
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
514
 
515
  stage1_info["state"] = "finished"
516
+ return {stage1_json : stage1_info,
517
  channel_json : channel_info,
518
  desc_md : gr.Markdown(md),
 
519
  out_result_file : gr.File(outputname, visible=True),
520
+ radio_group : gr.Radio(visible=False),
521
  clear_btn : gr.Button(visible=False),
522
+ next_btn : gr.Button(visible=False),
523
+ run_btn : gr.Button(interactive=True)}
524
  # step2 to step3-1
525
  else:
526
  md = """
 
528
  Select one of the methods provided below to fill the remaining template channels.
529
  """
530
  stage1_info["state"] = "step3-select-method"
531
+ return {stage1_json : stage1_info,
532
  channel_json : channel_info,
533
  desc_md : gr.Markdown(md),
534
  radio_group : gr.Radio(visible=False),
 
542
  # step3-1 to step4
543
  if fillmode == "zero":
544
  md = """
545
+ ### Mapping Result
546
  The mapping process has been finished.
547
  Download the file below if you plan to run the models using the <a href="">source code</a>.
548
  """
 
550
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
551
 
552
  stage1_info["state"] = "finished"
553
+ return {stage1_json : stage1_info,
554
  channel_json : channel_info,
555
  desc_md : gr.Markdown(md),
556
+ out_result_file : gr.File(outputname, visible=True),
557
  in_fillmode : gr.Dropdown(visible=False),
558
  fillmode_btn : gr.Button(visible=False),
559
+ run_btn : gr.Button(interactive=True)}
560
  # step3-1 to step3-2
561
  elif fillmode == "mean":
562
  md = """
 
565
  value of the data from the selected channels. (By default, the 4 nearest channels are pre-selected.)
566
  """
567
  # find the 4 nearest in_channels for each unmatched tpl_channels
568
+ stage1_info["mappingResult"][0]["newOrder"] = app_utils.find_neighbors(
569
  channel_info,
570
  stage1_info["emptyTemplates"],
571
+ stage1_info["mappingResult"][0]["newOrder"])
572
  # initialize the progress indication label
573
  stage1_info["step3"] = {
574
  "count" : 1,
 
578
  label = '{} (1/{})'.format(tpl_name, stage1_info["step3"]["totalNum"])
579
 
580
  tpl_idx = channel_info["templateDict"][tpl_name]["index"]
581
+ value = stage1_info["mappingResult"][0]["newOrder"][tpl_idx]
582
  value = [channel_info["inputNames"][i] for i in value]
583
 
584
  stage1_info["state"] = "step3-2-selecting"
585
  # determine which button to display
586
  if stage1_info["step3"]["totalNum"] == 1:
587
+ return {stage1_json : stage1_info,
588
  desc_md : gr.Markdown(md),
589
  in_fillmode : gr.Dropdown(visible=False),
590
  fillmode_btn : gr.Button(visible=False),
 
592
  value=value, label=label, visible=True),
593
  next_btn : gr.Button(visible=True)}
594
  else:
595
+ return {stage1_json : stage1_info,
596
  desc_md : gr.Markdown(md),
597
  in_fillmode : gr.Dropdown(visible=False),
598
  fillmode_btn : gr.Button(visible=False),
 
607
  prev_tpl_name = stage1_info["emptyTemplates"][stage1_info["step3"]["count"]-1]
608
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
609
  sel_idx = [channel_info["inputDict"][name]["index"] for name in sel_chkbox]
610
+ stage1_info["mappingResult"][0]["newOrder"][prev_tpl_idx] = sel_idx if sel_idx!=[] else [None]
611
  #print(prev_tpl_name, '<-', sel_chkbox)
612
  # ----------------------------------------------------------------------------------
613
  md = """
614
+ ### Mapping Result
615
  The mapping process has been finished.
616
  Download the file below if you plan to run the models using the <a href="">source code</a>.
617
  """
 
619
  stage1_info, channel_info = app_utils.mapping_result(stage1_info, channel_info, outputname)
620
 
621
  stage1_info["state"] = "finished"
622
+ return {stage1_json : stage1_info,
623
  channel_json : channel_info,
624
  desc_md : gr.Markdown(md),
625
+ out_result_file : gr.File(outputname, visible=True),
626
  chkbox_group : gr.CheckboxGroup(visible=False),
627
  next_btn : gr.Button(visible=False),
628
+ run_btn : gr.Button(interactive=True)}
629
 
630
  next_btn.click(
631
  fn = init_next_step,
632
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
633
+ outputs = [stage1_json, channel_json, desc_md, out_result_file, tpl_img, mapped_img, radio_group,
634
+ in_fillmode, fillmode_btn, chkbox_group, clear_btn, step2_btn, step3_btn, next_btn, run_btn]
635
  ).success(
636
  fn = None,
637
  js = init_js,
 
646
  map_btn.click(
647
  fn = reset_all,
648
  inputs = [stage1_json, stage2_json, in_loc_file],
649
+ outputs = [stage1_json, stage2_json, channel_json, map_btn, desc_md, out_result_file, tpl_img, mapped_img,
650
+ radio_group, in_fillmode, fillmode_btn, chkbox_group, clear_btn, step2_btn, step3_btn, next_btn,
651
+ in_data_file, in_samplerate, run_btn, cancel_btn, batch_md, out_data_file]
652
  ).success(
653
  fn = init_next_step,
654
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
 
686
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
687
  sel_idx = channel_info["inputDict"][sel_name]["index"]
688
 
689
+ stage1_info["mappingResult"][0]["newOrder"][prev_tpl_idx] = [sel_idx]
690
+ stage1_info["mappingResult"][0]["isOriginalData"][prev_tpl_idx] = True
691
  channel_info["templateDict"][prev_tpl_name]["matched"] = True
692
  channel_info["inputDict"][sel_name]["assigned"] = True
693
  #print(prev_tpl_name, '<-', sel_name)
 
736
  prev_tpl_name = stage1_info["emptyTemplates"][step3["count"]-1]
737
  prev_tpl_idx = channel_info["templateDict"][prev_tpl_name]["index"]
738
  sel_idx = [channel_info["inputDict"][name]["index"] for name in sel_name]
739
+ stage1_info["mappingResult"][0]["newOrder"][prev_tpl_idx] = sel_idx if sel_idx!=[] else [None]
740
  #print(prev_tpl_name, '<-', sel_name)
741
 
742
  # ---------------------------------update the new round---------------------------------
 
746
  label = '{} ({}/{})'.format(tpl_name, step3["count"], step3["totalNum"])
747
 
748
  tpl_idx = channel_info["templateDict"][tpl_name]["index"]
749
+ value = stage1_info["mappingResult"][0]["newOrder"][tpl_idx]
750
  value = [channel_info["inputNames"][i] for i in value]
751
 
752
  stage1_info["step3"] = step3
 
763
  fillmode_btn.click(
764
  fn = init_next_step,
765
  inputs = [stage1_json, channel_json, in_fillmode, radio_group, chkbox_group],
766
+ outputs = [stage1_json, channel_json, desc_md, out_result_file, in_fillmode, fillmode_btn,
767
+ chkbox_group, step3_btn, next_btn, run_btn]
768
  ).success(
769
  fn = None,
770
  js = init_js,
 
786
 
787
  # +========================================================================================+
788
  # | Stage2: decode data |
789
+ # +========================================================================================+
 
 
 
 
 
 
 
 
790
  @cancel_btn.click(inputs = stage2_json, outputs = [stage2_json, cancel_btn, batch_md])
791
  def stop_stage2(stage2_info):
792
  utils.dataDelete(stage2_info["filePath"])
793
  stage2_info["state"] = "stopped"
794
  return stage2_info, gr.Button(interactive=False), gr.Markdown(visible=False)
795
 
796
+ def reset_stage2(stage2_info, in_data, samplerate, modelname):
797
+ if in_data==None or samplerate=="":
798
+ gr.Warning("Please upload a file and enter the sampling rate.")
799
+ stage2_info["errorFlag"] = True
800
+ return {stage2_json : stage2_info}
801
+
802
  rootpath = os.path.dirname(str(in_data))
803
  # delete the previous folder(s) of Stage2
804
  folders = [ f.path for f in os.scandir(rootpath) if f.is_dir()]
 
818
  "outputData" : rootpath+'/'+stage2_id+'/'+outputname
819
  },
820
  "state" : "running",
821
+ "errorFlag" : False
822
  }
823
  return {stage2_json : stage2_info,
824
  run_btn : gr.Button(visible=False),
 
826
  batch_md : gr.Markdown("", visible=True),
827
  out_data_file : gr.File(value=None, visible=False)}
828
 
829
+ def run_stage2(stage1_info, stage2_info, samplerate, modelname):
830
+ if stage2_info["errorFlag"] == True:
831
+ stage2_info["errorFlag"] = False
832
+ yield {stage2_json : stage2_info}
 
 
 
833
 
834
+ else:
835
+ inputname = stage2_info["fileNames"]["inputData"]
836
+ outputname = stage2_info["fileNames"]["outputData"]
837
+ out_basename = os.path.basename(str(outputname))
838
+ out_basename = os.path.splitext(out_basename)[0]
839
 
840
+ for i in range(stage1_info["batchNum"]):
841
+ yield {batch_md : gr.Markdown('Running model({}/{})...'.format(i+1, stage1_info["batchNum"]))}
 
 
 
 
 
842
 
843
+ break_flag = app_utils.run_model(modelname = modelname,
844
+ filepath = stage2_info["filePath"],
845
+ inputname = inputname,
846
+ m_filename = 'mapped_{:02d}.csv'.format(i+1),
847
+ d_filename = '{}_{:02d}.csv'.format(out_basename, i+1),
848
+ outputname = outputname,
849
+ samplerate = int(samplerate),
850
+ batch_cnt = i,
851
+ new_idx = stage1_info["mappingResult"][i]["newOrder"],
852
+ orig_flags = stage1_info["mappingResult"][i]["isOriginalData"])
853
+ if break_flag == True:
854
+ break
855
+
856
+ if break_flag == True:
857
+ yield {run_btn : gr.Button(visible=True),
858
+ cancel_btn : gr.Button(visible=False)}
859
  else:
860
+ stage2_info["state"] = "finished"
861
+ yield {stage2_json : stage2_info,
862
+ run_btn : gr.Button(visible=True),
863
+ cancel_btn : gr.Button(visible=False),
864
+ batch_md : gr.Markdown(visible=False),
865
+ out_data_file : gr.File(outputname, visible=True)}
 
 
 
 
 
 
866
 
867
  run_btn.click(
868
  fn = reset_stage2,
869
+ inputs = [stage2_json, in_data_file, in_samplerate, in_modelname],
870
  outputs = [stage2_json, run_btn, cancel_btn, batch_md, out_data_file]
871
  ).success(
872
+ fn = run_stage2,
873
+ inputs = [stage1_json, stage2_json, in_samplerate, in_modelname],
874
  outputs = [stage2_json, run_btn, cancel_btn, batch_md, out_data_file]
875
  )
876
 
app_utils.py CHANGED
@@ -11,41 +11,6 @@ from scipy.interpolate import Rbf
11
  from scipy.optimize import linear_sum_assignment
12
  from sklearn.neighbors import NearestNeighbors
13
 
14
- def reorder_data(idx_order, orig_flags, inputname, filename):
15
- # read the input data
16
- raw_data = utils.read_train_data(inputname)
17
- #print(raw_data.shape)
18
- new_data = np.zeros((30, raw_data.shape[1]))
19
-
20
- zero_arr = np.zeros((1, raw_data.shape[1]))
21
- for i, (idx_set, flag) in enumerate(zip(idx_order, orig_flags)):
22
- if flag == True:
23
- new_data[i, :] = raw_data[idx_set[0], :]
24
- elif idx_set == [None]:
25
- new_data[i, :] = zero_arr
26
- else:
27
- tmp_data = [raw_data[j, :] for j in idx_set]
28
- new_data[i, :] = np.mean(tmp_data, axis=0)
29
-
30
- utils.save_data(new_data, filename)
31
- return raw_data.shape
32
-
33
- def restore_order(batch_cnt, raw_data_shape, idx_order, orig_flags, filename, outputname):
34
- # read the denoised data
35
- d_data = utils.read_train_data(filename)
36
- if batch_cnt == 0:
37
- new_data = np.zeros((raw_data_shape[0], d_data.shape[1]))
38
- #print(new_data.shape)
39
- else:
40
- new_data = utils.read_train_data(outputname)
41
-
42
- for i, (idx_set, flag) in enumerate(zip(idx_order, orig_flags)):
43
- if flag == True:
44
- new_data[idx_set[0], :] = d_data[i, :]
45
-
46
- utils.save_data(new_data, outputname)
47
- return
48
-
49
  def get_matched(tpl_names, tpl_dict):
50
  return [name for name in tpl_names if tpl_dict[name]["matched"]==True]
51
 
@@ -261,7 +226,7 @@ def match_names(stage1_info):
261
  stage1_info.update({
262
  "unassignedInputs" : get_unassigned_inputs(in_names, in_dict),
263
  "emptyTemplates" : get_empty_templates(tpl_names, tpl_dict),
264
- "mappingResults" : [
265
  {
266
  "newOrder" : new_idx,
267
  "isOriginalData" : orig_flags
@@ -303,7 +268,7 @@ def optimal_mapping(channel_info):
303
  # by minimizing the total distances between their positions.
304
  row_idx, col_idx = linear_sum_assignment(cost_matrix)
305
 
306
- # store the mapping results
307
  new_idx = [[None]]*30
308
  orig_flags = [False]*30
309
  for i, j in zip(row_idx, col_idx):
@@ -337,7 +302,7 @@ def mapping_result(stage1_info, channel_info, filename):
337
  batch_num = math.ceil(unassigned_num/30) + 1
338
 
339
  # map the remaining in_channels
340
- results = stage1_info["mappingResults"]
341
  for i in range(1, batch_num):
342
  # optimally select 30 in_channels to map to the tpl_channels based on proximity
343
  result, channel_info = optimal_mapping(channel_info)
@@ -347,17 +312,78 @@ def mapping_result(stage1_info, channel_info, filename):
347
  #"templateNames" : channel_info["templateNames"],
348
  #"inputNames" : channel_info["inputNames"],
349
  "batchNum" : batch_num,
350
- "mappingResults" : results
351
  }
352
  options = jsbeautifier.default_options()
353
  options.indent_size = 4
354
- res = jsbeautifier.beautify(json.dumps(data), options)
355
  with open(filename, 'w') as jsonfile:
356
- jsonfile.write(res)
357
 
358
  stage1_info.update({
359
  "batchNum" : batch_num,
360
- "mappingResults" : results
361
  })
362
  return stage1_info, channel_info
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  from scipy.optimize import linear_sum_assignment
12
  from sklearn.neighbors import NearestNeighbors
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def get_matched(tpl_names, tpl_dict):
15
  return [name for name in tpl_names if tpl_dict[name]["matched"]==True]
16
 
 
226
  stage1_info.update({
227
  "unassignedInputs" : get_unassigned_inputs(in_names, in_dict),
228
  "emptyTemplates" : get_empty_templates(tpl_names, tpl_dict),
229
+ "mappingResult" : [
230
  {
231
  "newOrder" : new_idx,
232
  "isOriginalData" : orig_flags
 
268
  # by minimizing the total distances between their positions.
269
  row_idx, col_idx = linear_sum_assignment(cost_matrix)
270
 
271
+ # store the mapping result
272
  new_idx = [[None]]*30
273
  orig_flags = [False]*30
274
  for i, j in zip(row_idx, col_idx):
 
302
  batch_num = math.ceil(unassigned_num/30) + 1
303
 
304
  # map the remaining in_channels
305
+ results = stage1_info["mappingResult"]
306
  for i in range(1, batch_num):
307
  # optimally select 30 in_channels to map to the tpl_channels based on proximity
308
  result, channel_info = optimal_mapping(channel_info)
 
312
  #"templateNames" : channel_info["templateNames"],
313
  #"inputNames" : channel_info["inputNames"],
314
  "batchNum" : batch_num,
315
+ "mappingResult" : results
316
  }
317
  options = jsbeautifier.default_options()
318
  options.indent_size = 4
319
+ json_data = jsbeautifier.beautify(json.dumps(data), options)
320
  with open(filename, 'w') as jsonfile:
321
+ jsonfile.write(json_data)
322
 
323
  stage1_info.update({
324
  "batchNum" : batch_num,
325
+ "mappingResult" : results
326
  })
327
  return stage1_info, channel_info
328
 
329
+
330
+ def reorder_data(idx_order, orig_flags, inputname, filename):
331
+ # read the input data
332
+ raw_data = utils.read_train_data(inputname)
333
+ #print(raw_data.shape)
334
+ new_data = np.zeros((30, raw_data.shape[1]))
335
+
336
+ zero_arr = np.zeros((1, raw_data.shape[1]))
337
+ for i, (idx_set, flag) in enumerate(zip(idx_order, orig_flags)):
338
+ if flag == True:
339
+ new_data[i, :] = raw_data[idx_set[0], :]
340
+ elif idx_set == [None]:
341
+ new_data[i, :] = zero_arr
342
+ else:
343
+ tmp_data = [raw_data[j, :] for j in idx_set]
344
+ new_data[i, :] = np.mean(tmp_data, axis=0)
345
+
346
+ utils.save_data(new_data, filename)
347
+ return raw_data.shape
348
+
349
+ def restore_order(batch_cnt, raw_data_shape, idx_order, orig_flags, filename, outputname):
350
+ # read the denoised data
351
+ d_data = utils.read_train_data(filename)
352
+ if batch_cnt == 0:
353
+ new_data = np.zeros((raw_data_shape[0], d_data.shape[1]))
354
+ #print(new_data.shape)
355
+ else:
356
+ new_data = utils.read_train_data(outputname)
357
+
358
+ for i, (idx_set, flag) in enumerate(zip(idx_order, orig_flags)):
359
+ if flag == True:
360
+ new_data[idx_set[0], :] = d_data[i, :]
361
+
362
+ utils.save_data(new_data, outputname)
363
+ return
364
+
365
+ def run_model(modelname, filepath, inputname, m_filename, d_filename, outputname, samplerate, batch_cnt, new_idx, orig_flags):
366
+ try:
367
+ # establish a temp folder
368
+ os.mkdir(filepath+'temp_data/')
369
+
370
+ # step1: Reorder input data
371
+ data_shape = reorder_data(new_idx, orig_flags, inputname, filepath+'temp_data/'+m_filename)
372
+ # step2: Data preprocessing
373
+ total_file_num = utils.preprocessing(filepath+'temp_data/', m_filename, samplerate)
374
+ # step3: Signal reconstruction
375
+ utils.reconstruct(modelname, total_file_num, filepath+'temp_data/', d_filename, samplerate)
376
+ # step4: Restore original order
377
+ restore_order(batch_cnt, data_shape, new_idx, orig_flags, filepath+'temp_data/'+d_filename, outputname)
378
+
379
+ except FileNotFoundError:
380
+ print('stop!!')
381
+ stop_flag = True
382
+
383
+ else:
384
+ utils.dataDelete(filepath+'temp_data/')
385
+ stop_flag = False
386
+
387
+ finally:
388
+ return stop_flag
389
+