Spaces:
Sleeping
Sleeping
Commit
·
ef20573
1
Parent(s):
995c1d0
update v3
Browse files- app.py +344 -190
- 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.
|
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.
|
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 |
-
|
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 |
-
|
195 |
-
|
|
|
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="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
|
208 |
-
#
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
272 |
-
|
273 |
-
run_btn : gr.Button(interactive=False),
|
274 |
tpl_montage : gr.Image(visible=False),
|
275 |
map_montage : gr.Image(value=None, visible=False),
|
276 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
283 |
-
|
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 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
|
|
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 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
).success(
|
384 |
-
|
385 |
-
|
386 |
-
outputs = [app_state_json,
|
387 |
-
|
388 |
).success(
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
outputs = []
|
393 |
)
|
394 |
-
|
395 |
|
396 |
-
def
|
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 |
-
|
404 |
-
|
|
|
|
|
|
|
|
|
405 |
|
406 |
-
#
|
407 |
-
|
408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
|
410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
|
412 |
-
#
|
413 |
-
app_state["
|
414 |
|
415 |
-
|
416 |
-
|
417 |
-
|
|
|
|
|
|
|
|
|
418 |
|
419 |
-
|
420 |
-
|
|
|
421 |
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
app_state["state"] = "finished"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
428 |
|
429 |
return {app_state_json : app_state,
|
430 |
-
|
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 |
-
|
438 |
-
|
439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
).success(
|
442 |
-
fn =
|
443 |
-
|
444 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
446 |
).success(
|
447 |
-
|
448 |
-
|
449 |
-
|
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
|
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 =
|
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 |
-
|
19 |
-
|
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 (
|
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
|
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 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
|
|
|
|
|
|
|
|
189 |
|
190 |
-
|
191 |
-
|
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,
|
|
|
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(
|
237 |
|
238 |
channel_info.update({
|
239 |
-
"
|
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 |
-
|
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 =
|
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.')
|