MNE-CPP  beta 1.0
selectionmanagerwindow.cpp
1 //=============================================================================================================
37 //*************************************************************************************************************
38 //=============================================================================================================
39 // INCLUDES
40 //=============================================================================================================
41 
42 #include "selectionmanagerwindow.h"
43 
44 
45 //*************************************************************************************************************
46 //=============================================================================================================
47 // USED NAMESPACES
48 //=============================================================================================================
49 
50 using namespace XDISPLIB;
51 
52 
53 //*************************************************************************************************************
54 //=============================================================================================================
55 // DEFINE MEMBER METHODS
56 //=============================================================================================================
57 
59  : QDockWidget(parent,Qt::Window)
60 , ui(new Ui::SelectionManagerWindow)
61 , m_pChInfoModel(pChInfoModel)
62 {
63  ui->setupUi(this);
64 
65  //Init gui elements
66  initListWidgets();
67  initSelectionSceneView();
68  initComboBoxes();
69 }
70 
71 
72 //*************************************************************************************************************
73 
75 {
76  delete ui;
77 }
78 
79 
80 //*************************************************************************************************************
81 
82 void SelectionManagerWindow::setCurrentlyMappedFiffChannels(const QStringList &mappedLayoutChNames)
83 {
84  std::cout<<"SelectionManagerWindow::setCurrentlyMappedFiffChannels"<<std::endl;
85  m_currentlyLoadedFiffChannels = mappedLayoutChNames;
86 
87  //Clear the visible channel list
88  ui->m_listWidget_visibleChannels->clear();
89 
90  //Keep the entry All in the selection list and m_selectionGroupsMap -> delete the rest
91  ui->m_listWidget_selectionGroups->clear();
92 
93  //Create group 'All' manually (bcause this group depends on the loaded channels from the fiff data file, not on the loaded selection file)
94  m_selectionGroupsMap["All"] = m_currentlyLoadedFiffChannels;
95 
96  //Add selection groups to list widget
97  QMapIterator<QString, QStringList> selectionIndex(m_selectionGroupsMap);
98  while (selectionIndex.hasNext()) {
99  selectionIndex.next();
100  ui->m_listWidget_selectionGroups->insertItem(ui->m_listWidget_selectionGroups->count(), selectionIndex.key());
101  }
102 
103  //Set group all as slected item
104  ui->m_listWidget_selectionGroups->setCurrentItem(getItemForChName(ui->m_listWidget_selectionGroups, "All"), QItemSelectionModel::Select);
105 
106  //Update selection
107  updateSelectionGroupsList(getItemForChName(ui->m_listWidget_selectionGroups, "All"), new QListWidgetItem());
108 }
109 
110 
111 //*************************************************************************************************************
112 
113 void SelectionManagerWindow::highlightChannels(QModelIndexList channelIndexList)
114 {
115  QStringList channelList;
116  for(int i = 0; i<channelIndexList.size(); i++) {
117  QModelIndex nameIndex = m_pChInfoModel->index(channelIndexList.at(i).row(),3);
118  channelList<<m_pChInfoModel->data(nameIndex, ChInfoModelRoles::GetMappedLayoutChName).toString();
119  }
120 
121  QList<QGraphicsItem *> allSceneItems = m_pSelectionScene->items();
122 
123  for(int i = 0; i<allSceneItems.size(); i++) {
124  SelectionSceneItem* item = static_cast<SelectionSceneItem*>(allSceneItems.at(i));
125  if(channelList.contains(item->m_sChannelName))
126  item->m_bHighlightItem = true;
127  else
128  item->m_bHighlightItem = false;
129  }
130 
131  m_pSelectionScene->update();
132 }
133 
134 
135 //*************************************************************************************************************
136 
137 void SelectionManagerWindow::selectChannels(QStringList channelList)
138 {
139  QList<QGraphicsItem *> allSceneItems = m_pSelectionScene->items();
140 
141  for(int i = 0; i<allSceneItems.size(); i++) {
142  SelectionSceneItem* item = static_cast<SelectionSceneItem*>(allSceneItems.at(i));
143  if(channelList.contains(item->m_sChannelName))
144  item->setSelected(true);
145  else
146  item->setSelected(false);
147  }
148 
149  m_pSelectionScene->update();
150 }
151 
152 
153 //*************************************************************************************************************
154 
156 {
157  //if no channels have been selected by the user -> show selected group channels
158  QListWidget* targetListWidget;
159  if(ui->m_listWidget_userDefined->count()>0)
160  targetListWidget = ui->m_listWidget_userDefined;
161  else
162  targetListWidget = ui->m_listWidget_visibleChannels;
163 
164  //Create list of channels which are to be visible in the view
165  QStringList selectedChannels;
166 
167  for(int i = 0; i<targetListWidget->count(); i++) {
168  QListWidgetItem* item = targetListWidget->item(i);
169  selectedChannels << item->text();
170  }
171 
172  return selectedChannels;
173 }
174 
175 
176 //*************************************************************************************************************
177 
178 QListWidgetItem* SelectionManagerWindow::getItemForChName(QListWidget* listWidget, QString channelName)
179 {
180  for(int i=0; i<listWidget->count(); i++)
181  if(listWidget->item(i)->text() == channelName)
182  return listWidget->item(i);
183 
184  return new QListWidgetItem();
185 }
186 
187 
188 //*************************************************************************************************************
189 
190 const QMap<QString,QPointF>& SelectionManagerWindow::getLayoutMap()
191 {
192  return m_layoutMap;
193 }
194 
195 
196 //*************************************************************************************************************
197 
199 {
200  loadLayout(ui->m_comboBox_layoutFile->currentText());
201 }
202 
203 
204 //*************************************************************************************************************
205 
206 void SelectionManagerWindow::initListWidgets()
207 {
208  //Install event filter to receive key press events
209  ui->m_listWidget_userDefined->installEventFilter(this);
210 
211  //Connect list widgets to update themselves and other list widgets when changed
212  connect(ui->m_listWidget_selectionGroups, &QListWidget::currentItemChanged,
213  this, &SelectionManagerWindow::updateSelectionGroupsList);
214 
215  //Update data view whenever a drag and drop item movement is performed - TODO: This is inefficient because updateDataView is called everytime the list's viewport is entered
216  connect(ui->m_listWidget_userDefined->model(), &QAbstractTableModel::dataChanged,
217  this, &SelectionManagerWindow::updateDataView);
218 }
219 
220 
221 //*************************************************************************************************************
222 
223 void SelectionManagerWindow::initSelectionSceneView()
224 {
225  //Create layout scene and set to view
226  m_pSelectionScene = new SelectionScene(ui->m_graphicsView_layoutPlot);
227  ui->m_graphicsView_layoutPlot->setScene(m_pSelectionScene);
228 
229  connect(m_pSelectionScene, &QGraphicsScene::selectionChanged,
230  this, &SelectionManagerWindow::updateUserDefinedChannelsList);
231 }
232 
233 
234 //*************************************************************************************************************
235 
236 void SelectionManagerWindow::initComboBoxes()
237 {
238  ui->m_comboBox_layoutFile->clear();
239  ui->m_comboBox_layoutFile->insertItems(0, QStringList()
240  << QApplication::translate("SelectionManagerWindow", "Vectorview-grad.lout", 0)
241  << QApplication::translate("SelectionManagerWindow", "Vectorview-all.lout", 0)
242  << QApplication::translate("SelectionManagerWindow", "Vectorview-mag.lout", 0)
243  << QApplication::translate("SelectionManagerWindow", "babymeg-mag-inner-layer.lout", 0)
244  << QApplication::translate("SelectionManagerWindow", "babymeg-mag-outer-layer.lout", 0)
245  << QApplication::translate("SelectionManagerWindow", "babymeg-mag-ref.lout", 0)
246 // << QApplication::translate("SelectionManagerWindow", "CTF-275.lout", 0)
247 // << QApplication::translate("SelectionManagerWindow", "magnesWH3600.lout", 0)
248  );
249  ui->m_comboBox_selectionFiles->clear();
250  ui->m_comboBox_selectionFiles->insertItems(0, QStringList()
251  << QApplication::translate("SelectionManagerWindow", "mne_browse_raw_vv.sel", 0)
252  << QApplication::translate("SelectionManagerWindow", "mne_browse_raw_vv_new.sel", 0)
253 // << QApplication::translate("SelectionManagerWindow", "mne_browse_raw_CTF_275.sel", 0)
254 // << QApplication::translate("SelectionManagerWindow", "mne_browse_raw_Magnes_3600WH.sel", 0)
255  );
256 
257  //Connect the layout and selection group loader
258  connect(ui->m_comboBox_selectionFiles, &QComboBox::currentTextChanged,
259  this, &SelectionManagerWindow::loadSelectionGroups);
260 
261  connect(ui->m_comboBox_layoutFile, &QComboBox::currentTextChanged,
262  this, &SelectionManagerWindow::loadLayout);
263 
264  //Initialise layout as neuromag vectorview with all channels
265  loadLayout("Vectorview-grad.lout");
266 }
267 
268 
269 //*************************************************************************************************************
270 
271 bool SelectionManagerWindow::loadLayout(QString path)
272 {
273  //Read layout
274  QString newPath = QCoreApplication::applicationDirPath() + path.prepend("/MNE_Browse_Raw_Resources/Templates/Layouts/");
275 
276  bool state = LayoutLoader::readMNELoutFile(newPath, m_layoutMap);
277 
278  //Load selection groups again because they need to be reinitialised every time a new layout hase been loaded
279  loadSelectionGroups(ui->m_comboBox_selectionFiles->currentText());
280 
281  //if no layout for EEG is specified generate from digitizer points
282  QList<QVector<double> > inputPoints;
283  QList<QVector<double> > outputPoints;
284  QStringList names;
285  QFile out;//(/*"./MNE_Browse_Raw_Resources/Templates/ChannelSelection/*/"manualLayout.lout");
286 
287  for(int i = 0; i<m_pChInfoModel->rowCount(); i++) {
288  QModelIndex digIndex = m_pChInfoModel->index(i,1);
289  QString chName = m_pChInfoModel->data(digIndex,ChInfoModelRoles::GetOrigChName).toString();
290 
291  digIndex = m_pChInfoModel->index(i,8);
292  QVector3D channelDig = m_pChInfoModel->data(digIndex,ChInfoModelRoles::GetChDigitizer).value<QVector3D>();
293 
294  digIndex = m_pChInfoModel->index(i,4);
295  int kind = m_pChInfoModel->data(digIndex,ChInfoModelRoles::GetChKind).toInt();
296 
297  if(kind == FIFFV_EEG_CH) { //FIFFV_MEG_CH
298  QVector<double> temp;
299  temp.append(channelDig.x());
300  temp.append(channelDig.y());
301  temp.append(-channelDig.z());
302  inputPoints.append(temp);
303 
304  names<<chName;
305  }
306  }
307 
308  float prad = 60.0;
309  float width = 5.0;
310  float height = 4.0;
311  int numberTries = 0;
312 
313  if(inputPoints.size()>0)
314  while(numberTries<10) {
315  if(LayoutMaker::makeLayout(inputPoints,
316  outputPoints,
317  names,
318  out,
319  true,
320  prad,
321  width,
322  height,
323  false) == -1)
324  numberTries++;
325  else
326  numberTries = 11;
327  }
328 
329  //Add new EEG points to Layout Map
330  for(int i = 0; i<outputPoints.size(); i++)
331  m_layoutMap[names.at(i)] = QPointF(outputPoints.at(i)[0],outputPoints.at(i)[1]);
332 
333  //Update scene
334  m_pSelectionScene->repaintItems(m_layoutMap);
335  m_pSelectionScene->update();
336  updateSceneItems();
337 
338  //Fit to view
339  ui->m_graphicsView_layoutPlot->fitInView(m_pSelectionScene->itemsBoundingRect(), Qt::KeepAspectRatio);
340 
341  if(state)
342  emit loadedLayoutMap(m_layoutMap);
343 
344  return state;
345 }
346 
347 
348 //*************************************************************************************************************
349 
350 bool SelectionManagerWindow::loadSelectionGroups(QString path)
351 {
352  //Clear the visible channel list
353  ui->m_listWidget_visibleChannels->clear();
354 
355  //Keep the entry All in the selection list and m_selectionGroupsMap -> delete the rest
356  ui->m_listWidget_selectionGroups->clear();
357 
358  //Read selection from file and store to map
359  SelectionLoader* manager = new SelectionLoader();
360  QString newPath = QCoreApplication::applicationDirPath() + path.prepend("/MNE_Browse_Raw_Resources/Templates/ChannelSelection/");
361 
362  m_selectionGroupsMap.clear();
363  bool state = manager->readMNESelFile(newPath, m_selectionGroupsMap);
364 
365  //Create group 'All' and 'All EEG' manually (bcause this group depends on the loaded channels from the fiff data file, not on the loaded selection file)
366  m_selectionGroupsMap["All"] = m_currentlyLoadedFiffChannels;
367 
368  QStringList names;
369  for(int i = 0; i<m_pChInfoModel->rowCount(); i++) {
370  QModelIndex digIndex = m_pChInfoModel->index(i,1);
371  QString chName = m_pChInfoModel->data(digIndex,ChInfoModelRoles::GetOrigChName).toString();
372 
373  digIndex = m_pChInfoModel->index(i,4);
374  int kind = m_pChInfoModel->data(digIndex,ChInfoModelRoles::GetChKind).toInt();
375 
376  if(kind == FIFFV_EEG_CH) //FIFFV_MEG_CH
377  names<<chName;
378  }
379 
380  //Add 'Add EEG' group to selection groups
381  m_selectionGroupsMap["All EEG"] = names;
382 
383  //Add selection groups to list widget
384  QMapIterator<QString, QStringList> selectionIndex(m_selectionGroupsMap);
385  while (selectionIndex.hasNext()) {
386  selectionIndex.next();
387  ui->m_listWidget_selectionGroups->insertItem(ui->m_listWidget_selectionGroups->count(), selectionIndex.key());
388  }
389 
390  //Update selection
391  updateSelectionGroupsList(getItemForChName(ui->m_listWidget_selectionGroups, "All"), new QListWidgetItem());
392 
393  //Set group all as slected item
394  ui->m_listWidget_selectionGroups->setCurrentItem(getItemForChName(ui->m_listWidget_selectionGroups, "All"), QItemSelectionModel::Select);
395 
396  //Delete all MEG channels from the selection groups which are not in the loaded layout
397  cleanUpMEGChannels();
398 
399  return state;
400 }
401 
402 
403 //*************************************************************************************************************
404 
405 void SelectionManagerWindow::cleanUpMEGChannels()
406 {
407  QMapIterator<QString,QStringList> selectionIndex(m_selectionGroupsMap);
408 
409  //Iterate through all loaded selection groups
410  while (selectionIndex.hasNext()) {
411  selectionIndex.next();
412 
413  QStringList channelList = selectionIndex.value();
414 
415  //Search the current selection group for MEG channels which are not in the currently loaded layout file and delete them
416  QMutableStringListIterator stringListIndex(channelList);
417  while (stringListIndex.hasNext()) {
418  stringListIndex.next();
419 
420  if(!m_layoutMap.contains(stringListIndex.value()) && stringListIndex.value().contains("MEG"))
421  stringListIndex.remove();
422  }
423 
424  //Overwrite old selection groups channels
425  m_selectionGroupsMap.insert(selectionIndex.key(), channelList);
426  }
427 }
428 
429 
430 //*************************************************************************************************************
431 
432 void SelectionManagerWindow::updateSelectionGroupsList(QListWidgetItem* current, QListWidgetItem* previous)
433 {
434  Q_UNUSED(previous);
435 
436  if(current == 0)
437  return;
438 
439  if(current->text().contains("EEG"))
440  m_pSelectionScene->m_iChannelTypeMode = FIFFV_EEG_CH;
441  else
442  m_pSelectionScene->m_iChannelTypeMode = FIFFV_MEG_CH;
443 
444  ui->m_listWidget_visibleChannels->clear();
445 
446  //update visible channel list widget
447  ui->m_listWidget_visibleChannels->addItems(m_selectionGroupsMap[current->text()]);
448 
449  //update scene items based o nthe new selection group
450  updateSceneItems();
451 
452  //update the channels plotted in the data view
453  updateDataView();
454 }
455 
456 
457 //*************************************************************************************************************
458 
459 void SelectionManagerWindow::updateSceneItems()
460 {
461  QStringList visibleItems;
462 
463  for(int i = 0; i<ui->m_listWidget_visibleChannels->count(); i++)
464  visibleItems << ui->m_listWidget_visibleChannels->item(i)->text();
465 
466  m_pSelectionScene->hideItems(visibleItems);
467 }
468 
469 
470 //*************************************************************************************************************
471 
472 void SelectionManagerWindow::updateUserDefinedChannelsList()
473 {
474  QList<QGraphicsItem*> itemList = m_pSelectionScene->selectedItems();
475  QStringList userDefinedChannels;
476 
477  for(int i = 0; i<itemList.size(); i++) {
478  SelectionSceneItem* item = static_cast<SelectionSceneItem*>(itemList.at(i));
479  userDefinedChannels << item->m_sChannelName;
480  }
481 
482  ui->m_listWidget_userDefined->clear();
483  ui->m_listWidget_userDefined->addItems(userDefinedChannels);
484 
485  updateDataView();
486 }
487 
488 
489 //*************************************************************************************************************
490 
491 void SelectionManagerWindow::updateDataView()
492 {
493  //if no channels have been selected by the user -> show selected group channels
494  QListWidget* targetListWidget;
495  if(ui->m_listWidget_userDefined->count()>0)
496  targetListWidget = ui->m_listWidget_userDefined;
497  else
498  targetListWidget = ui->m_listWidget_visibleChannels;
499 
500  //Create list of channels which are to be visible in the view
501  QStringList selectedChannels;
502 
503  for(int i = 0; i<targetListWidget->count(); i++) {
504  QListWidgetItem* item = targetListWidget->item(i);
505  int indexTemp = m_pChInfoModel->getIndexFromMappedChName(item->text());
506 
507  if(indexTemp != -1) {
508  QModelIndex mappedNameIndex = m_pChInfoModel->index(indexTemp,1);
509  QString origChName = m_pChInfoModel->data(mappedNameIndex,ChInfoModelRoles::GetOrigChName).toString();
510 
511  selectedChannels << origChName;
512  }
513  else
514  selectedChannels << item->text();
515  }
516 
517  emit showSelectedChannelsOnly(selectedChannels);
518 
519  //emit signal that selection was changed
520  if(!m_pSelectionScene->selectedItems().empty())
521  emit selectionChanged(m_pSelectionScene->selectedItems());
522  else
523  {
524  //only return visible items (EEG or MEG channels)
525  QList<QGraphicsItem*> visibleItemList = m_pSelectionScene->items();
526  QMutableListIterator<QGraphicsItem*> i(visibleItemList);
527  while (i.hasNext()) {
528  if(!i.next()->isVisible())
529  i.remove();
530  }
531 
532  emit selectionChanged(visibleItemList);
533  }
534 }
535 
536 
537 //*************************************************************************************************************
538 
539 void SelectionManagerWindow::resizeEvent(QResizeEvent* event)
540 {
541  Q_UNUSED(event);
542 
543  //Fit scene in view
544  //ui->m_graphicsView_layoutPlot->fitInView(m_pSelectionScene->itemsBoundingRect(), Qt::KeepAspectRatio);
545 }
546 
547 
548 //*************************************************************************************************************
549 
550 bool SelectionManagerWindow::eventFilter(QObject *obj, QEvent *event)
551 {
552  //Setup delete key on user defined channel list
553  if (obj == ui->m_listWidget_userDefined && event->type() == QEvent::KeyRelease) {
554  QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
555 
556  if(keyEvent->key() == Qt::Key_Delete) {
557  qDeleteAll(ui->m_listWidget_userDefined->selectedItems());
558  updateDataView();
559  }
560  else
561  return false;
562  }
563  else {
564  // pass the event on to the parent class
565  return QDockWidget::eventFilter(obj, event);
566  }
567 
568  return false;
569 }
void selectChannels(QStringList channelList)
void setCurrentlyMappedFiffChannels(const QStringList &mappedLayoutChNames)
int getIndexFromMappedChName(QString chName)
Definition: aboutwindow.h:52
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: chinfomodel.cpp:67
static bool readMNELoutFile(QString path, QMap< QString, QPointF > &channelData)
void showSelectedChannelsOnly(QStringList selectedChannels)
The SelectionManagerWindow class provides a channel selection window.
void loadedLayoutMap(const QMap< QString, QPointF > &layoutMap)
The SelectionScene class provides a reimplemented QGraphicsScene for 2D layout plotting.
static bool makeLayout(const QList< QVector< double > > &inputPoints, QList< QVector< double > > &outputPoints, const QStringList &names, QFile &outFile, bool do_fit, float prad, float w, float h, bool writeFile=false)
Definition: layoutmaker.cpp:73
void highlightChannels(QModelIndexList channelIndexList)
const QMap< QString, QPointF > & getLayoutMap()
void hideItems(QStringList visibleItems)
SelectionManagerWindow(QWidget *parent=0, ChInfoModel *pChInfoModel=0)
void selectionChanged(const QList< QGraphicsItem * > &selectedChannelItems)
void repaintItems(const QMap< QString, QPointF > &layoutMap)
Processes selection files (mne .sel) files which contain the chanels for each selection group...
bool readMNESelFile(QString path, QMap< QString, QStringList > &selectionMap)
QListWidgetItem * getItemForChName(QListWidget *listWidget, QString channelName)
The SelectionSceneItem class provides a new data structure for visualizing channels in a 2D layout...