celldetective 1.1.1.post1__py3-none-any.whl → 1.1.1.post4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,8 @@ from PyQt5.QtWidgets import QMainWindow, QApplication,QRadioButton, QMessageBox,
2
2
  from PyQt5.QtCore import Qt, QSize
3
3
  from PyQt5.QtGui import QDoubleValidator, QIntValidator, QIcon
4
4
  from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, GeometryChoice, OperationChoice
5
+ from celldetective.gui.layouts import ChannelNormGenerator
6
+
5
7
  from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider,QLabeledSlider
6
8
  from superqt.fonticon import icon
7
9
  from fonticon_mdi6 import MDI6
@@ -91,6 +93,8 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
91
93
  self.main_layout.addWidget(self.submit_btn)
92
94
  self.submit_btn.setEnabled(False)
93
95
 
96
+ self.spatial_calib_le.textChanged.connect(self.activate_train_btn)
97
+
94
98
  #self.populate_left_panel()
95
99
  #grid.addLayout(self.left_side, 0, 0, 1, 1)
96
100
  self.button_widget.adjustSize()
@@ -308,83 +312,25 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
308
312
  # layout.addLayout(recompile_layout)
309
313
 
310
314
  self.max_nbr_channels = 5
311
- self.channel_cbs = [QComboBox() for i in range(self.max_nbr_channels)]
312
- self.normalization_mode_btns = [QPushButton('') for i in range(self.max_nbr_channels)]
313
- self.normalization_mode = [True for i in range(self.max_nbr_channels)]
314
-
315
- self.normalization_clip_btns = [QPushButton('') for i in range(self.max_nbr_channels)]
316
- self.clip_option = [False for i in range(self.max_nbr_channels)]
317
-
318
- for i in range(self.max_nbr_channels):
319
-
320
- self.normalization_mode_btns[i].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
321
- self.normalization_mode_btns[i].setIconSize(QSize(20, 20))
322
- self.normalization_mode_btns[i].setStyleSheet(self.button_select_all)
323
- self.normalization_mode_btns[i].setToolTip("Switch to absolute normalization values.")
324
- self.normalization_mode_btns[i].clicked.connect(partial(self.switch_normalization_mode, i))
325
-
326
- self.normalization_clip_btns[i].setIcon(icon(MDI6.content_cut,color="black"))
327
- self.normalization_clip_btns[i].setIconSize(QSize(20, 20))
328
- self.normalization_clip_btns[i].setStyleSheet(self.button_select_all)
329
- self.normalization_clip_btns[i].clicked.connect(partial(self.switch_clipping_mode, i))
330
- self.normalization_clip_btns[i].setToolTip('clip')
331
-
332
- self.normalization_min_value_lbl = [QLabel('Min %: ') for i in range(self.max_nbr_channels)]
333
- self.normalization_min_value_le = [QLineEdit('0.1') for i in range(self.max_nbr_channels)]
334
-
335
- self.normalization_max_value_lbl = [QLabel('Max %: ') for i in range(self.max_nbr_channels)]
336
- self.normalization_max_value_le = [QLineEdit('99.99') for i in range(self.max_nbr_channels)]
337
-
338
- self.channel_items = ['--', 'brightfield_channel', 'live_nuclei_channel', 'dead_nuclei_channel',
339
- 'effector_fluo_channel', 'adhesion_channel', 'fluo_channel_1', 'fluo_channel_2','None'
340
- ]
341
- exp_ch = self.parent_window.parent_window.exp_channels
342
- for c in exp_ch:
343
- if c not in self.channel_items:
344
- self.channel_items.append(c)
345
-
346
- self.channel_option_layouts = []
347
- for i in range(len(self.channel_cbs)):
348
- ch_layout = QHBoxLayout()
349
- ch_layout.addWidget(QLabel(f'channel {i}: '), 30)
350
- self.channel_cbs[i].addItems(self.channel_items)
351
- self.channel_cbs[i].currentIndexChanged.connect(self.check_valid_channels)
352
- ch_layout.addWidget(self.channel_cbs[i], 70)
353
- layout.addLayout(ch_layout)
354
-
355
- channel_norm_options_layout = QHBoxLayout()
356
- channel_norm_options_layout.setContentsMargins(130,0,0,0)
357
- channel_norm_options_layout.addWidget(self.normalization_min_value_lbl[i])
358
- channel_norm_options_layout.addWidget(self.normalization_min_value_le[i])
359
- channel_norm_options_layout.addWidget(self.normalization_max_value_lbl[i])
360
- channel_norm_options_layout.addWidget(self.normalization_max_value_le[i])
361
- channel_norm_options_layout.addWidget(self.normalization_clip_btns[i])
362
- channel_norm_options_layout.addWidget(self.normalization_mode_btns[i])
363
- layout.addLayout(channel_norm_options_layout)
364
-
365
- # for i in range(self.max_nbr_channels):
366
- # self.channel_cbs[i].currentIndexChanged.connect(partial(self.show_norm_options, i))
315
+ self.ch_norm = ChannelNormGenerator(self, mode='channels')
316
+ layout.addLayout(self.ch_norm)
367
317
 
368
318
  spatial_calib_layout = QHBoxLayout()
369
319
  spatial_calib_layout.addWidget(QLabel('input spatial\ncalibration'), 30)
370
- self.spatial_calib_le = QLineEdit('')
320
+ parent_pxtoum = f"{self.parent_window.parent_window.PxToUm}"
321
+ self.spatial_calib_le = QLineEdit(parent_pxtoum.replace('.',','))
371
322
  self.spatial_calib_le.setPlaceholderText('e.g. 0.1 µm per pixel')
323
+ self.spatial_calib_le.setValidator(self.onlyFloat)
372
324
  spatial_calib_layout.addWidget(self.spatial_calib_le, 70)
373
325
  layout.addLayout(spatial_calib_layout)
374
326
 
375
327
 
376
- # model_length_layout = QHBoxLayout()
377
- # model_length_layout.addWidget(QLabel('Max signal length: '), 30)
378
- # self.model_length_slider = QLabeledSlider()
379
- # self.model_length_slider.setSingleStep(1)
380
- # self.model_length_slider.setTickInterval(1)
381
- # self.model_length_slider.setSingleStep(1)
382
- # self.model_length_slider.setOrientation(1)
383
- # self.model_length_slider.setRange(0,1024)
384
- # self.model_length_slider.setValue(128)
385
- # model_length_layout.addWidget(self.model_length_slider, 70)
386
- # layout.addLayout(model_length_layout)
387
328
 
329
+ def activate_train_btn(self):
330
+ if self.spatial_calib_le.text()=='':
331
+ self.submit_btn.setEnabled(False)
332
+ elif not np.all([cb.currentText()=='--' for cb in self.ch_norm.channel_cbs]):
333
+ self.submit_btn.setEnabled(True)
388
334
 
389
335
  def rescale_slider(self):
390
336
  if self.stardist_model.isChecked():
@@ -400,36 +346,44 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
400
346
  except:
401
347
  pass
402
348
 
349
+ self.pretrained_model = None
403
350
  self.pretrained_model = QFileDialog.getExistingDirectory(
404
351
  self, "Open Directory",
405
352
  os.sep.join([self.soft_path, 'celldetective', 'models', f'segmentation_generic','']),
406
353
  QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks,
407
354
  )
355
+
356
+ if self.pretrained_model=='':
357
+ return None
358
+
359
+ if self.pretrained_model is None:
360
+ return None
408
361
 
409
- if self.pretrained_model is not None:
410
-
362
+ else:
411
363
  self.pretrained_model = self.pretrained_model.replace('\\','/')
412
364
  self.pretrained_model = rf"{self.pretrained_model}"
413
365
 
414
- subfiles = glob('/'.join([self.pretrained_model,"*"]))
366
+ subfiles = glob(os.sep.join([self.pretrained_model,"*"]))
415
367
  subfiles = [s.replace('\\','/') for s in subfiles]
416
368
  subfiles = [rf"{s}" for s in subfiles]
417
369
 
418
- if '/'.join([self.pretrained_model,"config_input.json"]) in subfiles:
370
+ if os.sep.join([self.pretrained_model,"config_input.json"]) in subfiles:
419
371
  self.load_pretrained_config()
420
372
  self.pretrained_lbl.setText(self.pretrained_model.split("/")[-1])
421
373
  self.cancel_pretrained.setVisible(True)
422
374
  #self.recompile_option.setEnabled(True)
423
- self.modelname_le.setText(f"{self.pretrained_model.split('/')[-1]}_{datetime.today().strftime('%Y-%m-%d')}")
375
+ self.modelname_le.setText(f"{self.pretrained_model.split(os.sep)[-1]}_{datetime.today().strftime('%Y-%m-%d')}")
424
376
  else:
425
377
  self.pretrained_model = None
426
378
  self.pretrained_lbl.setText('No folder chosen')
427
379
  #self.recompile_option.setEnabled(False)
428
380
  self.cancel_pretrained.setVisible(False)
381
+ return None
382
+
429
383
  print(self.pretrained_model)
430
384
 
431
- self.seg_folder = self.pretrained_model.split('/')[-2]
432
- self.model_name = self.pretrained_model.split('/')[-1]
385
+ self.seg_folder = self.pretrained_model.split(os.sep)[-2]
386
+ self.model_name = self.pretrained_model.split(os.sep)[-1]
433
387
  if self.model_name.startswith('CP') and self.seg_folder=='segmentation_generic':
434
388
 
435
389
  self.diamWidget = QWidget()
@@ -456,7 +410,7 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
456
410
  scale = self.parent_window.parent_window.PxToUm * float(self.diameter_le.text()) / 30.0
457
411
  if self.model_name=="CP_nuclei":
458
412
  scale = self.parent_window.parent_window.PxToUm * float(self.diameter_le.text()) / 17.0
459
- self.spatial_calib_le.setText(str(scale))
413
+ self.spatial_calib_le.setText(str(scale).replace('.',','))
460
414
  self.diamWidget.close()
461
415
 
462
416
 
@@ -485,14 +439,15 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
485
439
 
486
440
  self.pretrained_model = None
487
441
  self.pretrained_lbl.setText('No folder chosen')
488
- for i in range(len(self.channel_cbs)):
489
- self.channel_cbs[i].setEnabled(True)
490
- self.normalization_mode_btns[i].setEnabled(True)
491
- self.normalization_max_value_le[i].setEnabled(True)
492
- self.normalization_min_value_le[i].setEnabled(True)
493
- self.normalization_clip_btns[i].setEnabled(True)
494
- self.normalization_min_value_lbl[i].setEnabled(True)
495
- self.normalization_max_value_lbl[i].setEnabled(True)
442
+ for i in range(len(self.ch_norm.channel_cbs)):
443
+ self.ch_norm.channel_cbs[i].setEnabled(True)
444
+ self.ch_norm.normalization_mode_btns[i].setEnabled(True)
445
+ self.ch_norm.normalization_max_value_le[i].setEnabled(True)
446
+ self.ch_norm.normalization_min_value_le[i].setEnabled(True)
447
+ self.ch_norm.normalization_clip_btns[i].setEnabled(True)
448
+ self.ch_norm.normalization_min_value_lbl[i].setEnabled(True)
449
+ self.ch_norm.normalization_max_value_lbl[i].setEnabled(True)
450
+ self.ch_norm.add_col_btn.setEnabled(True)
496
451
 
497
452
  self.cancel_pretrained.setVisible(False)
498
453
  self.modelname_le.setText(f"Untitled_model_{datetime.today().strftime('%Y-%m-%d')}")
@@ -507,7 +462,7 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
507
462
 
508
463
  def load_pretrained_config(self):
509
464
 
510
- f = open('/'.join([self.pretrained_model,"config_input.json"]))
465
+ f = open(os.sep.join([self.pretrained_model,"config_input.json"]))
511
466
  data = json.load(f)
512
467
  channels = data["channels"]
513
468
  self.seg_folder = self.pretrained_model.split('/')[-2]
@@ -533,36 +488,37 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
533
488
  self.stardist_model.setChecked(False)
534
489
  self.cellpose_model.setChecked(True)
535
490
 
536
- for c,cb in zip(channels, self.channel_cbs):
491
+ for c,cb in zip(channels, self.ch_norm.channel_cbs):
537
492
  index = cb.findText(c)
538
493
  cb.setCurrentIndex(index)
539
494
 
540
495
  for i in range(len(channels)):
541
496
 
542
497
  to_clip = normalization_clip[i]
543
- if self.clip_option[i] != to_clip:
544
- self.normalization_clip_btns[i].click()
498
+ if self.ch_norm.clip_option[i] != to_clip:
499
+ self.ch_norm.normalization_clip_btns[i].click()
545
500
 
546
501
  use_percentile = normalization_percentile[i]
547
- if self.normalization_mode[i] != use_percentile:
548
- self.normalization_mode_btns[i].click()
502
+ if self.ch_norm.normalization_mode[i] != use_percentile:
503
+ self.ch_norm.normalization_mode_btns[i].click()
549
504
 
550
- self.normalization_min_value_le[i].setText(str(normalization_values[i][0]))
551
- self.normalization_max_value_le[i].setText(str(normalization_values[i][1]))
505
+ self.ch_norm.normalization_min_value_le[i].setText(str(normalization_values[i][0]))
506
+ self.ch_norm.normalization_max_value_le[i].setText(str(normalization_values[i][1]))
552
507
 
553
508
 
554
- if len(channels)<len(self.channel_cbs):
555
- for k in range(len(self.channel_cbs)-len(channels)):
556
- self.channel_cbs[len(channels)+k].setCurrentIndex(0)
557
- self.channel_cbs[len(channels)+k].setEnabled(False)
558
- self.normalization_mode_btns[len(channels)+k].setEnabled(False)
559
- self.normalization_max_value_le[len(channels)+k].setEnabled(False)
560
- self.normalization_min_value_le[len(channels)+k].setEnabled(False)
561
- self.normalization_min_value_lbl[len(channels)+k].setEnabled(False)
562
- self.normalization_max_value_lbl[len(channels)+k].setEnabled(False)
563
- self.normalization_clip_btns[len(channels)+k].setEnabled(False)
509
+ if len(channels)<len(self.ch_norm.channel_cbs):
510
+ for k in range(len(self.ch_norm.channel_cbs)-len(channels)):
511
+ self.ch_norm.channel_cbs[len(channels)+k].setCurrentIndex(0)
512
+ self.ch_norm.channel_cbs[len(channels)+k].setEnabled(False)
513
+ self.ch_norm.normalization_mode_btns[len(channels)+k].setEnabled(False)
514
+ self.ch_norm.normalization_max_value_le[len(channels)+k].setEnabled(False)
515
+ self.ch_norm.normalization_min_value_le[len(channels)+k].setEnabled(False)
516
+ self.ch_norm.normalization_min_value_lbl[len(channels)+k].setEnabled(False)
517
+ self.ch_norm.normalization_max_value_lbl[len(channels)+k].setEnabled(False)
518
+ self.ch_norm.normalization_clip_btns[len(channels)+k].setEnabled(False)
519
+ self.ch_norm.add_col_btn.setEnabled(False)
564
520
 
565
- self.spatial_calib_le.setText(str(spatial_calib))
521
+ self.spatial_calib_le.setText(str(spatial_calib).replace('.',','))
566
522
 
567
523
  def adjustScrollArea(self):
568
524
 
@@ -581,23 +537,23 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
581
537
  pretrained_model = self.pretrained_model
582
538
 
583
539
  channels = []
584
- for i in range(len(self.channel_cbs)):
585
- channels.append(self.channel_cbs[i].currentText())
540
+ for i in range(len(self.ch_norm.channel_cbs)):
541
+ channels.append(self.ch_norm.channel_cbs[i].currentText())
586
542
 
587
543
  slots_to_keep = np.where(np.array(channels)!='--')[0]
588
544
  while '--' in channels:
589
545
  channels.remove('--')
590
546
 
591
- norm_values = np.array([[float(a.replace(',','.')),float(b.replace(',','.'))] for a,b in zip([l.text() for l in self.normalization_min_value_le],
592
- [l.text() for l in self.normalization_max_value_le])])
547
+ norm_values = np.array([[float(a.replace(',','.')),float(b.replace(',','.'))] for a,b in zip([l.text() for l in self.ch_norm.normalization_min_value_le],
548
+ [l.text() for l in self.ch_norm.normalization_max_value_le])])
593
549
  norm_values = norm_values[slots_to_keep]
594
550
  norm_values = [list(v) for v in norm_values]
595
551
 
596
- clip_values = np.array(self.clip_option)
552
+ clip_values = np.array(self.ch_norm.clip_option)
597
553
  clip_values = list(clip_values[slots_to_keep])
598
554
  clip_values = [bool(c) for c in clip_values]
599
555
 
600
- normalization_mode = np.array(self.normalization_mode)
556
+ normalization_mode = np.array(self.ch_norm.normalization_mode)
601
557
  normalization_mode = list(normalization_mode[slots_to_keep])
602
558
  normalization_mode = [bool(m) for m in normalization_mode]
603
559
 
@@ -650,58 +606,4 @@ class ConfigSegmentationModelTraining(QMainWindow, Styles):
650
606
 
651
607
  train_segmentation_model(model_folder+"training_instructions.json", use_gpu=self.parent_window.parent_window.parent_window.use_gpu)
652
608
 
653
- # self.parent.refresh_signal_models()
654
-
655
-
656
- def check_valid_channels(self):
657
-
658
- if np.all([cb.currentText()=='--' for cb in self.channel_cbs]):
659
- self.submit_btn.setEnabled(False)
660
- else:
661
- self.submit_btn.setEnabled(True)
662
-
663
-
664
- def switch_normalization_mode(self, index):
665
-
666
- """
667
- Use absolute or percentile values for the normalization of each individual channel.
668
-
669
- """
670
-
671
- currentNormMode = self.normalization_mode[index]
672
- self.normalization_mode[index] = not currentNormMode
673
-
674
- if self.normalization_mode[index]:
675
- self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
676
- self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
677
- self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
678
- self.normalization_mode_btns[index].setToolTip("Switch to absolute normalization values.")
679
- self.normalization_min_value_lbl[index].setText('Min %: ')
680
- self.normalization_max_value_lbl[index].setText('Max %: ')
681
- self.normalization_min_value_le[index].setText('0.1')
682
- self.normalization_max_value_le[index].setText('99.99')
683
-
684
- else:
685
- self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle_outline,color="black"))
686
- self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
687
- self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
688
- self.normalization_mode_btns[index].setToolTip("Switch to percentile normalization values.")
689
- self.normalization_min_value_lbl[index].setText('Min: ')
690
- self.normalization_min_value_le[index].setText('0')
691
- self.normalization_max_value_lbl[index].setText('Max: ')
692
- self.normalization_max_value_le[index].setText('1000')
693
-
694
- def switch_clipping_mode(self, index):
695
-
696
- currentClipMode = self.clip_option[index]
697
- self.clip_option[index] = not currentClipMode
698
-
699
- if self.clip_option[index]:
700
- self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="#1565c0"))
701
- self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
702
- self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
703
-
704
- else:
705
- self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="black"))
706
- self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
707
- self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
609
+ # self.parent.refresh_signal_models()
@@ -2,6 +2,7 @@ from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QScrollArea,
2
2
  from PyQt5.QtCore import Qt, QSize
3
3
  from PyQt5.QtGui import QDoubleValidator, QIntValidator, QIcon
4
4
  from celldetective.gui.gui_utils import center_window, FeatureChoice, ListWidget, QHSeperationLine, FigureCanvas, GeometryChoice, OperationChoice
5
+ from celldetective.gui.layouts import ChannelNormGenerator
5
6
  from superqt import QLabeledDoubleRangeSlider, QLabeledDoubleSlider,QLabeledSlider
6
7
  from superqt.fonticon import icon
7
8
  from fonticon_mdi6 import MDI6
@@ -306,103 +307,9 @@ class ConfigSignalModelTraining(QMainWindow, Styles):
306
307
  recompile_layout.addWidget(self.recompile_option, 70)
307
308
  layout.addLayout(recompile_layout)
308
309
 
309
- #self.channel_cbs = [QComboBox() for i in range(4)]
310
-
311
310
  self.max_nbr_channels = 5
312
- self.channel_cbs = [QComboBox() for i in range(self.max_nbr_channels)]
313
- self.normalization_mode_btns = [QPushButton('') for i in range(self.max_nbr_channels)]
314
- self.normalization_mode = [True for i in range(self.max_nbr_channels)]
315
-
316
- self.normalization_clip_btns = [QPushButton('') for i in range(self.max_nbr_channels)]
317
- self.clip_option = [False for i in range(self.max_nbr_channels)]
318
-
319
- for i in range(self.max_nbr_channels):
320
-
321
- self.normalization_mode_btns[i].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
322
- self.normalization_mode_btns[i].setIconSize(QSize(20, 20))
323
- self.normalization_mode_btns[i].setStyleSheet(self.button_select_all)
324
- self.normalization_mode_btns[i].setToolTip("Switch to absolute normalization values.")
325
- self.normalization_mode_btns[i].clicked.connect(partial(self.switch_normalization_mode, i))
326
-
327
- self.normalization_clip_btns[i].setIcon(icon(MDI6.content_cut,color="black"))
328
- self.normalization_clip_btns[i].setIconSize(QSize(20, 20))
329
- self.normalization_clip_btns[i].setStyleSheet(self.button_select_all)
330
- self.normalization_clip_btns[i].clicked.connect(partial(self.switch_clipping_mode, i))
331
- self.normalization_clip_btns[i].setToolTip('clip')
332
-
333
- self.normalization_min_value_lbl = [QLabel('Min %: ') for i in range(self.max_nbr_channels)]
334
- self.normalization_min_value_le = [QLineEdit('0.1') for i in range(self.max_nbr_channels)]
335
-
336
- self.normalization_max_value_lbl = [QLabel('Max %: ') for i in range(self.max_nbr_channels)]
337
- self.normalization_max_value_le = [QLineEdit('99.99') for i in range(self.max_nbr_channels)]
338
-
339
- tables = glob(self.exp_dir+os.sep.join(['W*','*','output','tables',f'trajectories_{self.mode}.csv']))
340
- print(tables)
341
- all_measurements = []
342
- for tab in tables:
343
- cols = pd.read_csv(tab, nrows=1).columns.tolist()
344
- all_measurements.extend(cols)
345
- all_measurements = np.unique(all_measurements)
346
- generic_measurements = ['brightfield_channel', 'live_nuclei_channel', 'dead_nuclei_channel',
347
- 'effector_fluo_channel', 'adhesion_channel', 'fluo_channel_1', 'fluo_channel_2',
348
- "area", "area_bbox","area_convex","area_filled","major_axis_length",
349
- "minor_axis_length",
350
- "eccentricity",
351
- "equivalent_diameter_area",
352
- "euler_number",
353
- "extent",
354
- "feret_diameter_max",
355
- "orientation",
356
- "perimeter",
357
- "perimeter_crofton",
358
- "solidity",
359
- "angular_second_moment",
360
- "contrast",
361
- "correlation",
362
- "sum_of_square_variance",
363
- "inverse_difference_moment",
364
- "sum_average",
365
- "sum_variance",
366
- "sum_entropy",
367
- "entropy",
368
- "difference_variance",
369
- "difference_entropy",
370
- "information_measure_of_correlation_1",
371
- "information_measure_of_correlation_2",
372
- "maximal_correlation_coefficient",
373
- "POSITION_X",
374
- "POSITION_Y",
375
- ]
376
-
377
- self.channel_items = np.unique(generic_measurements + list(all_measurements))
378
- self.channel_items = np.insert(self.channel_items, 0, '--')
379
-
380
- self.channel_option_layouts = []
381
- for i in range(len(self.channel_cbs)):
382
- ch_layout = QHBoxLayout()
383
- ch_layout.addWidget(QLabel(f'channel {i}: '), 30)
384
- self.channel_cbs[i].addItems(self.channel_items)
385
- self.channel_cbs[i].currentIndexChanged.connect(self.check_valid_channels)
386
- ch_layout.addWidget(self.channel_cbs[i], 70)
387
- layout.addLayout(ch_layout)
388
-
389
- channel_norm_options_layout = QHBoxLayout()
390
- channel_norm_options_layout.setContentsMargins(130,0,0,0)
391
- channel_norm_options_layout.addWidget(self.normalization_min_value_lbl[i])
392
- channel_norm_options_layout.addWidget(self.normalization_min_value_le[i])
393
- channel_norm_options_layout.addWidget(self.normalization_max_value_lbl[i])
394
- channel_norm_options_layout.addWidget(self.normalization_max_value_le[i])
395
- channel_norm_options_layout.addWidget(self.normalization_clip_btns[i])
396
- channel_norm_options_layout.addWidget(self.normalization_mode_btns[i])
397
- layout.addLayout(channel_norm_options_layout)
398
-
399
- # for i in range(len(self.channel_cbs)):
400
- # ch_layout = QHBoxLayout()
401
- # ch_layout.addWidget(QLabel(f'channel {i}: '), 30)
402
- # self.channel_cbs[i].addItems(self.channel_items)
403
- # self.channel_cbs[i].currentIndexChanged.connect(self.check_valid_channels)
404
- # ch_layout.addWidget(self.channel_cbs[i], 70)
405
- # layout.addLayout(ch_layout)
311
+ self.ch_norm = ChannelNormGenerator(self, mode='signals')
312
+ layout.addLayout(self.ch_norm)
406
313
 
407
314
  model_length_layout = QHBoxLayout()
408
315
  model_length_layout.addWidget(QLabel('Max signal length: '), 30)
@@ -465,8 +372,9 @@ class ConfigSignalModelTraining(QMainWindow, Styles):
465
372
 
466
373
  self.pretrained_model = None
467
374
  self.pretrained_lbl.setText('No folder chosen')
468
- for cb in self.channel_cbs:
375
+ for cb in self.ch_norm.channel_cbs:
469
376
  cb.setEnabled(True)
377
+ self.ch_norm.add_col_btn.setEnabled(True)
470
378
  self.recompile_option.setEnabled(False)
471
379
  self.cancel_pretrained.setVisible(False)
472
380
  self.model_length_slider.setEnabled(True)
@@ -495,14 +403,15 @@ class ConfigSignalModelTraining(QMainWindow, Styles):
495
403
  self.model_length_slider.setValue(int(signal_length))
496
404
  self.model_length_slider.setEnabled(False)
497
405
 
498
- for c,cb in zip(channels, self.channel_cbs):
406
+ for c,cb in zip(channels, self.ch_norm.channel_cbs):
499
407
  index = cb.findText(c)
500
408
  cb.setCurrentIndex(index)
501
409
 
502
- if len(channels)<len(self.channel_cbs):
503
- for k in range(len(self.channel_cbs)-len(channels)):
504
- self.channel_cbs[len(channels)+k].setCurrentIndex(0)
505
- self.channel_cbs[len(channels)+k].setEnabled(False)
410
+ if len(channels)<len(self.ch_norm.channel_cbs):
411
+ for k in range(len(self.ch_norm.channel_cbs)-len(channels)):
412
+ self.ch_norm.channel_cbs[len(channels)+k].setCurrentIndex(0)
413
+ self.ch_norm.channel_cbs[len(channels)+k].setEnabled(False)
414
+ self.ch_norm.add_col_btn.setEnabled(False)
506
415
 
507
416
 
508
417
  def adjustScrollArea(self):
@@ -524,23 +433,23 @@ class ConfigSignalModelTraining(QMainWindow, Styles):
524
433
  recompile_op = self.recompile_option.isChecked()
525
434
 
526
435
  channels = []
527
- for i in range(len(self.channel_cbs)):
528
- channels.append(self.channel_cbs[i].currentText())
436
+ for i in range(len(self.ch_norm.channel_cbs)):
437
+ channels.append(self.ch_norm.channel_cbs[i].currentText())
529
438
 
530
439
  slots_to_keep = np.where(np.array(channels)!='--')[0]
531
440
  while '--' in channels:
532
441
  channels.remove('--')
533
442
 
534
- norm_values = np.array([[float(a.replace(',','.')),float(b.replace(',','.'))] for a,b in zip([l.text() for l in self.normalization_min_value_le],
535
- [l.text() for l in self.normalization_max_value_le])])
443
+ norm_values = np.array([[float(a.replace(',','.')),float(b.replace(',','.'))] for a,b in zip([l.text() for l in self.ch_norm.normalization_min_value_le],
444
+ [l.text() for l in self.ch_norm.normalization_max_value_le])])
536
445
  norm_values = norm_values[slots_to_keep]
537
446
  norm_values = [list(v) for v in norm_values]
538
447
 
539
- clip_values = np.array(self.clip_option)
448
+ clip_values = np.array(self.ch_norm.clip_option)
540
449
  clip_values = list(clip_values[slots_to_keep])
541
450
  clip_values = [bool(c) for c in clip_values]
542
451
 
543
- normalization_mode = np.array(self.normalization_mode)
452
+ normalization_mode = np.array(self.ch_norm.normalization_mode)
544
453
  normalization_mode = list(normalization_mode[slots_to_keep])
545
454
  normalization_mode = [bool(m) for m in normalization_mode]
546
455
 
@@ -586,59 +495,4 @@ class ConfigSignalModelTraining(QMainWindow, Styles):
586
495
 
587
496
  train_signal_model(model_folder+"training_instructions.json")
588
497
 
589
- self.parent_window.refresh_signal_models()
590
-
591
-
592
- def check_valid_channels(self):
593
-
594
- if np.all([cb.currentText()=='--' for cb in self.channel_cbs]):
595
- self.submit_btn.setEnabled(False)
596
- else:
597
- self.submit_btn.setEnabled(True)
598
-
599
-
600
- def switch_normalization_mode(self, index):
601
-
602
- """
603
- Use absolute or percentile values for the normalization of each individual channel.
604
-
605
- """
606
-
607
- currentNormMode = self.normalization_mode[index]
608
- self.normalization_mode[index] = not currentNormMode
609
-
610
- if self.normalization_mode[index]:
611
- self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle,color="#1565c0"))
612
- self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
613
- self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
614
- self.normalization_mode_btns[index].setToolTip("Switch to absolute normalization values.")
615
- self.normalization_min_value_lbl[index].setText('Min %: ')
616
- self.normalization_max_value_lbl[index].setText('Max %: ')
617
- self.normalization_min_value_le[index].setText('0.1')
618
- self.normalization_max_value_le[index].setText('99.99')
619
-
620
- else:
621
- self.normalization_mode_btns[index].setIcon(icon(MDI6.percent_circle_outline,color="black"))
622
- self.normalization_mode_btns[index].setIconSize(QSize(20, 20))
623
- self.normalization_mode_btns[index].setStyleSheet(self.button_select_all)
624
- self.normalization_mode_btns[index].setToolTip("Switch to percentile normalization values.")
625
- self.normalization_min_value_lbl[index].setText('Min: ')
626
- self.normalization_min_value_le[index].setText('0')
627
- self.normalization_max_value_lbl[index].setText('Max: ')
628
- self.normalization_max_value_le[index].setText('1000')
629
-
630
- def switch_clipping_mode(self, index):
631
-
632
- currentClipMode = self.clip_option[index]
633
- self.clip_option[index] = not currentClipMode
634
-
635
- if self.clip_option[index]:
636
- self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="#1565c0"))
637
- self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
638
- self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
639
-
640
- else:
641
- self.normalization_clip_btns[index].setIcon(icon(MDI6.content_cut,color="black"))
642
- self.normalization_clip_btns[index].setIconSize(QSize(20, 20))
643
- self.normalization_clip_btns[index].setStyleSheet(self.button_select_all)
644
-
498
+ self.parent_window.refresh_signal_models()