MNE-CPP  beta 1.0
rawdelegate.cpp
Go to the documentation of this file.
1 //=============================================================================================================
38 //*************************************************************************************************************
39 //=============================================================================================================
40 // INCLUDES
41 //=============================================================================================================
42 
43 #include "rawdelegate.h"
44 
45 
46 //*************************************************************************************************************
47 //=============================================================================================================
48 // Qt INCLUDES
49 //=============================================================================================================
50 
51 #include <QBrush>
52 
53 
54 //*************************************************************************************************************
55 //=============================================================================================================
56 // USED NAMESPACES
57 //=============================================================================================================
58 
59 using namespace MNEBrowseRawQt;
60 
61 
62 //*************************************************************************************************************
63 //=============================================================================================================
64 // DEFINE MEMBER METHODS
65 //=============================================================================================================
66 
67 RawDelegate::RawDelegate(QObject *parent)
68 : QAbstractItemDelegate(parent)
69 , m_qSettings()
70 , m_bShowSelectedEventsOnly(false)
71 , m_bActivateEvents(true)
72 , m_bRemoveDC(false)
73 {
74  m_iDefaultPlotHeight = DELEGATE_PLOT_HEIGHT;
75  m_dDx = DELEGATE_DX;
76  m_nhlines = DELEGATE_NHLINES;
77 
78  m_pEventModel = new EventModel(NULL);
79  m_pEventView = new QTableView(NULL);
80  m_pRawView = new QTableView(NULL);
81 
82  //Init m_scaleMap
83  m_scaleMap["MEG_grad"] = 400 * 1e-15 * 100; //*100 because data in fiff files is stored as fT/m not fT/cm
84  m_scaleMap["MEG_mag"] = 1.2 * 1e-12;
85  m_scaleMap["MEG_EEG"] = 30 * 1e-06;
86  m_scaleMap["MEG_EOG"] = 150 * 1e-06;
87  m_scaleMap["MEG_EMG"] = 1 * 1e-03;
88  m_scaleMap["MEG_ECG"] = 1 * 1e-03;
89  m_scaleMap["MEG_MISC"] = 1 * 1;
90  m_scaleMap["MEG_STIM"] = 5 * 1;
91 }
92 
93 
94 //*************************************************************************************************************
95 
96 void RawDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
97 {
98  float t_fPlotHeight = option.rect.height();
99  switch(index.column()) {
100  case 0: { //chnames
101  painter->save();
102 
103  painter->rotate(-90);
104  painter->drawText(QRectF(-option.rect.y()-t_fPlotHeight,0,t_fPlotHeight,20),Qt::AlignCenter,index.model()->data(index,Qt::DisplayRole).toString());
105 
106  painter->restore();
107  break;
108  }
109  case 1: { //data plot
110  painter->save();
111 
112  //draw special background when channel is marked as bad
113  QVariant v = index.model()->data(index,Qt::BackgroundRole);
114  if(v.canConvert<QBrush>()/* && !(option.state & QStyle::State_Selected)*/) {
115  QPointF oldBO = painter->brushOrigin();
116  painter->setBrushOrigin(option.rect.topLeft());
117  painter->fillRect(option.rect, qvariant_cast<QBrush>(v));
118  painter->setBrushOrigin(oldBO);
119  }
120 
121  //Get data and mean
122  QVariant variant = index.model()->data(index,Qt::DisplayRole);
123  QList<RowVectorPair> listPairs = variant.value<QList<RowVectorPair> >();
124 
125  double channelMean = 0;
126  if(m_bRemoveDC) {
127  QModelIndex meanIndex = index.model()->index(index.row(),2);
128  QVariant channelMeanVariant = index.model()->data(meanIndex,RawModelRoles::GetChannelMean);
129  channelMean = channelMeanVariant.toDouble();
130  }
131 
132  const RawModel* t_rawModel = (static_cast<const RawModel*>(index.model()));
133 
134  QPainterPath path(QPointF(option.rect.x()+t_rawModel->relFiffCursor()-1,option.rect.y()));
135 
136  //Plot grid
137  painter->setRenderHint(QPainter::Antialiasing, false);
138  createGridPath(path,option,listPairs);
139 
140  painter->save();
141  QPen pen;
142  pen.setStyle(Qt::DotLine);
143  pen.setWidthF(0.5);
144  painter->setPen(pen);
145  painter->drawPath(path);
146  painter->restore();
147 
148  //Plot data path
149  path = QPainterPath(QPointF(option.rect.x()+t_rawModel->relFiffCursor(), option.rect.y()));
150  createPlotPath(index, option, path, listPairs, channelMean);
151 
152  if(option.state & QStyle::State_Selected) {
153  pen.setStyle(Qt::SolidLine);
154  pen.setWidthF(1);
155  pen.setColor(Qt::red);
156  painter->setPen(pen);
157  }
158 
159  painter->translate(0,t_fPlotHeight/2);
160  painter->setRenderHint(QPainter::Antialiasing, true);
161  painter->drawPath(path);
162  painter->restore();
163 
164  //Plot events
165  painter->save();
166  if(m_pEventModel->rowCount()!=0 && m_bActivateEvents)
167  plotEvents(index, option, painter);
168  painter->restore();
169 
170  break;
171  }
172  }
173 }
174 
175 
176 //*************************************************************************************************************
177 
178 QSize RawDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
179 {
180  QSize size;
181 
182  switch(index.column()) {
183  case 0:
184  size = QSize(20,option.rect.height());
185  break;
186  case 1:
187  QList<RowVectorPair> listPairs = index.model()->data(index).value<QList<RowVectorPair> >();
188  qint32 nsamples = (static_cast<const RawModel*>(index.model()))->lastSample()-(static_cast<const RawModel*>(index.model()))->firstSample();
189 
190  size = QSize(nsamples*m_dDx,option.rect.height());
191  break;
192  }
193 
194  Q_UNUSED(option);
195 
196  return size;
197 }
198 
199 
200 //*************************************************************************************************************
201 
202 void RawDelegate::setModelView(EventModel *eventModel, QTableView* eventView, QTableView* rawView)
203 {
204  m_pEventModel = eventModel;
205  m_pEventView = eventView;
206  m_pRawView = rawView;
207 }
208 
209 
210 //*************************************************************************************************************
211 
212 void RawDelegate::setScaleMap(const QMap<QString,double> &scaleMap)
213 {
214  m_scaleMap = scaleMap;
215 }
216 
217 
218 //*************************************************************************************************************
219 
220 void RawDelegate::createPlotPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, QList<RowVectorPair>& listPairs, double channelMean) const
221 {
222  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
223  qint32 kind = (static_cast<const RawModel*>(index.model()))->m_chInfolist[index.row()].kind;
224  double dMaxValue = 1e-9;
225 
226  switch(kind) {
227  case FIFFV_MEG_CH: {
228  qint32 unit = (static_cast<const RawModel*>(index.model()))->m_pfiffIO->m_qlistRaw[0]->info.chs[index.row()].unit;
229  if(unit == FIFF_UNIT_T_M) {
230  dMaxValue = m_scaleMap["MEG_grad"];
231  }
232  else if(unit == FIFF_UNIT_T)
233  dMaxValue = m_scaleMap["MEG_mag"];
234  break;
235  }
236  case FIFFV_EEG_CH: {
237  dMaxValue = m_scaleMap["MEG_EEG"];
238  break;
239  }
240  case FIFFV_EOG_CH: {
241  dMaxValue = m_scaleMap["MEG_EOG"];
242  break;
243  }
244  case FIFFV_STIM_CH: {
245  dMaxValue = m_scaleMap["MEG_STIM"];
246  break;
247  }
248  case FIFFV_EMG_CH: {
249  dMaxValue = m_scaleMap["MEG_EMG"];
250  break;
251  }
252  case FIFFV_MISC_CH: {
253  dMaxValue = m_scaleMap["MEG_MISC"];
254  break;
255  }
256  }
257 
258  double dValue;
259  double dScaleY = option.rect.height()/(2*dMaxValue);
260 
261  double y_base = -path.currentPosition().y();
262  QPointF qSamplePosition;
263 
264  path.moveTo(path.currentPosition().x(), -(y_base + ((*(listPairs[0].first) - channelMean)*dScaleY)));
265 
266  //plot all rows from list of pairs
267  for(qint8 i=0; i < listPairs.size(); ++i) {
268  //create lines from one to the next sample
269  for(qint32 j=0; j < listPairs[i].second; ++j)
270  {
271  double val = *(listPairs[i].first+j);
272 
273  //subtract mean of the channel here (if wanted by the user)
274  dValue = (val - channelMean)*dScaleY;
275 
276  double newY = y_base+dValue;
277 
278  qSamplePosition.setY(-newY);
279  qSamplePosition.setX(path.currentPosition().x()+m_dDx);
280 
281  path.lineTo(qSamplePosition);
282  }
283  }
284 
285 // qDebug("Plot-PainterPath created!");
286 }
287 
288 
289 //*************************************************************************************************************
290 
291 void RawDelegate::createGridPath(QPainterPath& path, const QStyleOptionViewItem &option, QList<RowVectorPair>& listPairs) const
292 {
293  //horizontal lines
294  double distance = option.rect.height()/m_nhlines;
295 
296  QPointF startpos = path.currentPosition();
297  QPointF endpoint(path.currentPosition().x()+listPairs[0].second*listPairs.size()*m_dDx,path.currentPosition().y());
298 
299  for(qint8 i=0; i < m_nhlines-1; ++i) {
300  endpoint.setY(endpoint.y()+distance);
301  path.moveTo(startpos.x(),endpoint.y());
302  path.lineTo(endpoint);
303  }
304 
305 // qDebug("Grid-PainterPath created!");
306 }
307 
308 
309 //*************************************************************************************************************
310 
311 void RawDelegate::plotEvents(const QModelIndex &index, const QStyleOptionViewItem &option, QPainter* painter) const
312 {
313  const RawModel* rawModel = static_cast<const RawModel*>(index.model());
314 
315  qint32 sampleRangeLow = rawModel->relFiffCursor();
316  qint32 sampleRangeHigh = sampleRangeLow + rawModel->sizeOfPreloadedData();
317 
318  QPen pen;
319  pen.setWidth(EVENT_MARKER_WIDTH);
320 
321  QColor colorTemp;
322 
323  QMap<int, QColor> eventTypeColor = m_pEventModel->getEventTypeColors();
324 
325  if(!m_bShowSelectedEventsOnly) { //Plot all events
326  for(int i = 0; i<m_pEventModel->rowCount(); i++) {
327  int sampleValue = m_pEventModel->data(m_pEventModel->index(i,0)).toInt();
328  int type = m_pEventModel->data(m_pEventModel->index(i,2)).toInt();
329 
330  if(sampleValue>=sampleRangeLow && sampleValue<=sampleRangeHigh) {
331  //Set color for pen depending on current event type
332  pen.setColor(eventTypeColor.value(type, Qt::black));
333 
334  colorTemp = pen.color();
335  colorTemp.setAlpha(EVENT_MARKER_OPACITY);
336  pen.setColor(colorTemp);
337  painter->setPen(pen);
338 
339  //Draw line from sample position (x) and highest to lowest y position of the column widget - Add -m_qSettings.value("EventDesignParameters/event_marker_width").toInt() to avoid painting ovre the edge of the column widget
340  painter->drawLine(option.rect.x() + sampleValue, option.rect.y(), option.rect.x() + sampleValue, option.rect.y() + option.rect.height() - EVENT_MARKER_WIDTH);
341  } // END for statement
342  } // END if statement event in data range
343  } // END if statement plot all
344  else { //Only plot selected events
345  QModelIndexList indexes = m_pEventView->selectionModel()->selectedIndexes();
346 
347  for(int i = 0; i<indexes.size(); i++) {
348  qDebug()<<indexes.at(i).row();
349  int currentRow = indexes.at(i).row();
350  int sampleValue = m_pEventModel->data(m_pEventModel->index(currentRow,0)).toInt();
351  int type = m_pEventModel->data(m_pEventModel->index(currentRow,2)).toInt();
352 
353  if(sampleValue>=sampleRangeLow && sampleValue<=sampleRangeHigh) {
354  //qDebug()<<"currentRow"<<currentRow<<"sampleValue"<<sampleValue<<"sampleRangeLow"<<sampleRangeLow<<"sampleRangeHigh"<<sampleRangeHigh;
355 
356  //Set color for pen depending on current event type
357  pen.setColor(eventTypeColor.value(type, Qt::black));
358 
359  colorTemp = pen.color();
360  colorTemp.setAlpha(EVENT_MARKER_OPACITY);
361  pen.setColor(colorTemp);
362  painter->setPen(pen);
363 
364  //Draw line from sample position (x) and highest to lowest y position of the column widget - Add +m_qSettings.value("EventDesignParameters/event_marker_width").toInt() to avoid painting ovre the edge of the column widget
365  painter->drawLine(option.rect.x() + sampleValue, option.rect.y(), option.rect.x() + sampleValue, option.rect.y() - option.rect.height() + EVENT_MARKER_WIDTH);
366  } // END for statement
367  } // END if statement
368  } // END else statement
369 }
370 
void setScaleMap(const QMap< QString, double > &scaleMap)
const QMap< int, QColor > & getEventTypeColors()
Definition: eventmodel.cpp:498
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: rawdelegate.cpp:96
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: eventmodel.cpp:103
#define FIFF_UNIT_T_M
This class represents the delegate of the model/view framework of mne_browse_raw_qt application...
QMap< QString, double > m_scaleMap
Definition: rawdelegate.h:155
qint32 relFiffCursor() const
Definition: rawmodel.h:540
qint32 sizeOfPreloadedData() const
Definition: rawmodel.h:530
void setModelView(EventModel *eventModel, QTableView *eventView, QTableView *rawView)