MNE-CPP  beta 1.0
realtimebutterflyplot.cpp
1 
2 //*************************************************************************************************************
3 //=============================================================================================================
4 // INCLUDES
5 //=============================================================================================================
6 
7 #include "realtimebutterflyplot.h"
8 #include "../realtimeevokedwidget.h"
9 
10 
11 //*************************************************************************************************************
12 //=============================================================================================================
13 // Qt INCLUDES
14 //=============================================================================================================
15 
16 #include <QPainter>
17 #include <QDebug>
18 #include <iostream>
19 
20 
21 //*************************************************************************************************************
22 //=============================================================================================================
23 // USED NAMESPACES
24 //=============================================================================================================
25 
26 using namespace XDISPLIB;
27 
28 
29 //*************************************************************************************************************
30 //=============================================================================================================
31 // DEFINE MEMBER METHODS
32 //=============================================================================================================
33 
34 RealTimeButterflyPlot::RealTimeButterflyPlot(QWidget *parent)
35 : QWidget(parent)
36 , m_pRealTimeEvokedModel(NULL)
37 , m_bIsInit(false)
38 , m_iNumChannels(-1)
39 , showMAG(true)
40 , showGRAD(false)
41 , showEEG(false)
42 , showEOG(false)
43 , showMISC(false)
44 {
45 }
46 
47 
48 //*************************************************************************************************************
49 
50 void RealTimeButterflyPlot::dataUpdate(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
51 {
52  if(!m_bIsInit && m_pRealTimeEvokedModel->isInit())
53  {
54  m_iNumChannels = m_pRealTimeEvokedModel->rowCount();
55  m_bIsInit = true;
56  }
57 
58  update();
59 }
60 
61 
62 //*************************************************************************************************************
63 
65 {
66 
67  QPainter painter(this);
68 
69  painter.save();
70  painter.setBrush(QBrush(Qt::white));
71  painter.drawRect(QRect(0,0,this->width()-1,this->height()-1));
72  painter.restore();
73 
74  if(m_bIsInit)
75  {
76  //Stimulus bar
77  if(m_pRealTimeEvokedModel->getNumSamples() > 0)
78  {
79 
80  painter.save();
81  painter.setPen(QPen(Qt::black, 1, Qt::DashLine));
82 
83  float fDx = (float)(this->width()-2) / ((float)m_pRealTimeEvokedModel->getNumSamples()-1.0f);
84  float posX = fDx * ((float)m_pRealTimeEvokedModel->getNumPreStimSamples()-1.0f);
85  painter.drawLine(posX, 1, posX, this->height()-2);
86 
87  painter.restore();
88  }
89 
90  painter.translate(0,this->height()/2);
91 
92  for(qint32 r = 0; r < m_iNumChannels; ++r)
93  {
94  if(m_lSelectedChannels.contains(r)) {
95  qint32 kind = m_pRealTimeEvokedModel->getKind(r);
96 
97  //Display only selected kinds
98  switch(kind) {
99  case FIFFV_MEG_CH: {
100  qint32 unit = m_pRealTimeEvokedModel->getUnit(r);
101  if(unit == FIFF_UNIT_T_M) {
102  if(showGRAD)
103  break;
104  else
105  continue;
106  }
107  else if(unit == FIFF_UNIT_T)
108  {
109  if(showMAG)
110  break;
111  else
112  continue;
113  }
114  continue;
115  }
116  case FIFFV_EEG_CH: {
117  if(showEEG)
118  break;
119  else
120  continue;
121  }
122  case FIFFV_EOG_CH: {
123  if(showEOG)
124  break;
125  else
126  continue;
127  }
128  case FIFFV_MISC_CH: {
129  if(showMISC)
130  break;
131  else
132  continue;
133  }
134  default:
135  continue;
136  }
137 
138  painter.save();
139  painter.setPen(QPen(m_pRealTimeEvokedModel->getColor(r), 1));
140 
141  QPainterPath path(QPointF(1,0));
142  createPlotPath(r,path);
143 
144  painter.drawPath(path);
145 
146  painter.restore();
147  }
148  }
149  }
150 }
151 
152 
153 //*************************************************************************************************************
154 
155 void RealTimeButterflyPlot::createPlotPath(qint32 row, QPainterPath& path) const
156 {
157  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
158  qint32 kind = m_pRealTimeEvokedModel->getKind(row);
159  float fMaxValue = 1e-9f;
160 
161  switch(kind) {
162  case FIFFV_MEG_CH: {
163  qint32 unit = m_pRealTimeEvokedModel->getUnit(row);
164  if(unit == FIFF_UNIT_T_M)
165  fMaxValue = fMaxGRAD;
166  else if(unit == FIFF_UNIT_T)
167  fMaxValue = fMaxMAG;
168  break;
169  }
170  case FIFFV_EEG_CH: {
171  fMaxValue = fMaxEEG;
172  break;
173  }
174  case FIFFV_EOG_CH: {
175  fMaxValue = fMaxEOG;
176  break;
177  }
178  case FIFFV_MISC_CH: {
179  fMaxValue = fMaxMISC;
180  break;
181  }
182  default:
183  return;
184  }
185 
186  float fValue;
187  float fScaleY = this->height()/(2*fMaxValue);
188 
189  //restrictions for paint performance
190  float fWinMaxVal = ((float)this->height()-2)/2.0f;
191  qint32 iDownSampling = (m_pRealTimeEvokedModel->getNumSamples() * 4 / (this->width()-2));
192  if(iDownSampling < 1)
193  iDownSampling = 1;
194 
195  float y_base = path.currentPosition().y();
196  QPointF qSamplePosition;
197 
198  float fDx = (float)(this->width()-2) / ((float)m_pRealTimeEvokedModel->getNumSamples()-1.0f);//((float)option.rect.width()) / t_pModel->getMaxSamples();
199 // fDx *= iDownSampling;
200 
201  RowVectorXd rowVec = m_pRealTimeEvokedModel->data(row,1).value<RowVectorXd>();
202  //Move to initial starting point
203  if(rowVec.size() > 0)
204  {
205  float val = rowVec[0];
206  fValue = (val-rowVec[m_pRealTimeEvokedModel->getNumPreStimSamples()-1])*fScaleY;//ToDo -> -2 PreStim is one too short
207 
208  float newY = y_base+fValue;
209 
210  qSamplePosition.setY(newY);
211  qSamplePosition.setX(path.currentPosition().x());
212 
213  path.moveTo(qSamplePosition);
214  }
215 
216  //create lines from one to the next sample
217  qint32 i;
218  for(i = 1; i < rowVec.size(); ++i) {
219 
220  if(i != m_pRealTimeEvokedModel->getNumPreStimSamples() - 2)
221  {
222  float val = rowVec[m_pRealTimeEvokedModel->getNumPreStimSamples()-1] - rowVec[i]; //remove first sample data[0] as offset
223  fValue = val*fScaleY;
224 
225  fValue = fValue > fWinMaxVal ? fWinMaxVal : fValue < -fWinMaxVal ? -fWinMaxVal : fValue;
226 
227  float newY = y_base+fValue;
228 
229  qSamplePosition.setY(newY);
230  }
231  else
232  qSamplePosition.setY(y_base);
233 
234 
235  qSamplePosition.setX(path.currentPosition().x()+fDx);
236 
237  path.lineTo(qSamplePosition);
238  }
239 
240 // //create lines from one to the next sample for last path
241 // qint32 sample_offset = t_pModel->numVLines() + 1;
242 // qSamplePosition.setX(qSamplePosition.x() + fDx*sample_offset);
243 // lastPath.moveTo(qSamplePosition);
244 
245 // for(i += sample_offset; i < lastData.size(); ++i) {
246 // float val = lastData[i] - lastData[0]; //remove first sample lastData[0] as offset
247 // fValue = val*fScaleY;
248 
249 // float newY = y_base+fValue;
250 
251 // qSamplePosition.setY(newY);
252 // qSamplePosition.setX(lastPath.currentPosition().x()+fDx);
253 
254 // lastPath.lineTo(qSamplePosition);
255 // }
256 }
257 
258 
259 //*************************************************************************************************************
260 
261 void RealTimeButterflyPlot::setSettings(const QList< Modality >& p_qListModalities)
262 {
263  for(qint32 i = 0; i < p_qListModalities.size(); ++i)
264  {
265  if(p_qListModalities[i].m_sName == ("GRAD"))
266  {
267  showGRAD = p_qListModalities[i].m_bActive;
268  fMaxGRAD = p_qListModalities[i].m_fNorm;
269  }
270 
271  if(p_qListModalities[i].m_sName == ("MAG"))
272  {
273  showMAG = p_qListModalities[i].m_bActive;
274  fMaxMAG = p_qListModalities[i].m_fNorm;
275  }
276  if(p_qListModalities[i].m_sName == ("EEG"))
277  {
278  showEEG = p_qListModalities[i].m_bActive;
279  fMaxEEG = p_qListModalities[i].m_fNorm;
280 
281  }
282  if(p_qListModalities[i].m_sName == ("EOG"))
283  {
284  showEOG = p_qListModalities[i].m_bActive;
285  fMaxEOG = p_qListModalities[i].m_fNorm;
286 
287  }
288  if(p_qListModalities[i].m_sName == ("MISC"))
289  {
290  showMISC = p_qListModalities[i].m_bActive;
291  fMaxMISC = p_qListModalities[i].m_fNorm;
292 
293  }
294  }
295  update();
296 }
297 
298 
299 //*************************************************************************************************************
300 
301 void RealTimeButterflyPlot::setSelectedChannels(const QList<int> &selectedChannels)
302 {
303  m_lSelectedChannels = selectedChannels;
304 
305  update();
306 }
QVariant data(int row, int column, int role=Qt::DisplayRole) const
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
fiff_int_t getKind(qint32 row) const
QColor getColor(qint32 row) const
fiff_int_t getUnit(qint32 row) const
#define FIFF_UNIT_T_M
virtual void paintEvent(QPaintEvent *event)