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