MNE-CPP  0.1.9
A Framework for Electrophysiology
averagesceneitem.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //=============================================================================================================
37 // INCLUDES
38 //=============================================================================================================
39 
40 #include "averagesceneitem.h"
41 #include "../scalingview.h"
42 
43 #include <fiff/fiff_types.h>
44 
45 //=============================================================================================================
46 // QT INCLUDES
47 //=============================================================================================================
48 
49 #include <QPainter>
50 #include <QDebug>
51 #include <QStaticText>
52 
53 //=============================================================================================================
54 // EIGEN INCLUDES
55 //=============================================================================================================
56 
57 //=============================================================================================================
58 // USED NAMESPACES
59 //=============================================================================================================
60 
61 using namespace DISPLIB;
62 
63 //=============================================================================================================
64 // DEFINE MEMBER METHODS
65 //=============================================================================================================
66 
67 AverageSceneItem::AverageSceneItem(const QString& channelName,
68  int channelNumber,
69  const QPointF &channelPosition,
70  int channelKind,
71  int channelUnit,
72  const QColor &color)
73 : m_sChannelName(channelName)
74 , m_iChannelNumber(channelNumber)
75 , m_iChannelKind(channelKind)
76 , m_iChannelUnit(channelUnit)
77 , m_iTotalNumberChannels(0)
78 , m_iFontTextSize(15)
79 , m_iMaxWidth(1500)
80 , m_iMaxHeigth(150)
81 , m_bIsBad(false)
82 , m_qpChannelPosition(channelPosition)
83 , m_colorDefault(color)
84 {
86 }
87 
88 //=============================================================================================================
89 
91 {
92  return m_rectBoundingRect;
93 }
94 
95 //=============================================================================================================
96 
97 void AverageSceneItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
98 {
99  Q_UNUSED(event)
100  m_iFontTextSize = 150;
101  emit sceneUpdateRequested();
102 }
103 
104 //=============================================================================================================
105 
106 void AverageSceneItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
107 {
108  Q_UNUSED(event)
109  m_iFontTextSize = 15;
110  emit sceneUpdateRequested();
111 }
112 
113 //=============================================================================================================
114 
115 void AverageSceneItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
116 {
117  Q_UNUSED(option);
118  Q_UNUSED(widget);
119 
120  //set posistion
121  this->setPos(75*m_qpChannelPosition.x(), -75*m_qpChannelPosition.y());
122 
123  painter->setRenderHint(QPainter::Antialiasing, true);
124 
125  if(m_bIsBad) {
126  painter->setOpacity(0.20);
127  }
128 
129 // //Plot bounding rect / drawing region of this item
130 // painter->drawRect(this->boundingRect());
131 
132  //Plot stim time
133  painter->save();
134  paintStimLine(painter);
135  painter->restore();
136 
137  //Plot average data
138  painter->save();
139  paintAveragePath(painter);
140  painter->restore();
141 
142  // Plot channel name
143  QStaticText staticElectrodeName = QStaticText(m_sChannelName);
144  painter->save();
145  QPen pen;
146  pen.setColor(Qt::red);
147  pen.setWidthF(5);
148 
149  QFont f = painter->font();
150  f.setPointSizeF(m_iFontTextSize);
151  painter->setFont(f);
152 
153  painter->setPen(pen);
154  painter->drawStaticText(boundingRect().x(), boundingRect().y()-(2*m_iFontTextSize), staticElectrodeName);
155  painter->restore();
156 
157  //Plot bounding rect
158 // painter->save();
159 // pen.setColor(Qt::red);
160 // painter->setPen(pen);
161 // painter->drawRect(this->boundingRect());
162 // painter->restore();
163 }
164 
165 //=============================================================================================================
166 
167 void AverageSceneItem::paintAveragePath(QPainter *painter)
168 {
169  if(m_lAverageData.size() == 0)
170  return;
171 
172  //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value)
173 
175 
176  //Plot averaged data
177  QRectF boundingRect = this->boundingRect();
178  double dScaleY = (boundingRect.height())/(2*fMaxValue);
179  QPointF qSamplePosition;
180 
181  //do for all currently stored evoked set data
182  for(int dataIndex = 0; dataIndex < m_lAverageData.size(); ++dataIndex) {
183  QString sAvrComment = m_lAverageData.at(dataIndex).first;
184 
185  if(m_qMapAverageActivation[sAvrComment]) {
186  //plot data from averaged data m_lAverageData with the calculated downsample factor
187  const double* averageData = m_lAverageData.at(dataIndex).second.first;
188  int totalCols = m_lAverageData.at(dataIndex).second.second;
189 
190  if(totalCols < m_iMaxWidth) {
191  m_rectBoundingRect = QRectF(-totalCols/2, -m_iMaxHeigth/2, totalCols, m_iMaxHeigth);
192  }
193 
194  //Calculate downsampling factor of averaged data in respect to the items width
195  int dsFactor;
196  totalCols / boundingRect.width()<1 ? dsFactor = 1 : dsFactor = totalCols / boundingRect.width();
197  if(dsFactor == 0) {
198  dsFactor = 1;
199  }
200 
201  //Create path
202  //float offset = (*(averageData+(0*m_iTotalNumberChannels)+m_iChannelNumber)); //choose offset to be the signal value at first sample
203  float offset = 0;
204  QPainterPath path = QPainterPath(QPointF(boundingRect.x(), boundingRect.y() + boundingRect.height()/2));
205  QPen pen;
206  pen.setStyle(Qt::SolidLine);
207  pen.setColor(m_colorDefault);
208 
209  if(m_qMapAverageColor.contains(sAvrComment)) {
210  pen.setColor(m_qMapAverageColor[sAvrComment]);
211  }
212 
213  pen.setWidthF(3);
214  painter->setPen(pen);
215 
216  for(int i = 0; i < totalCols && path.elementCount() <= boundingRect.width(); i += dsFactor) {
217  //evoked matrix is stored in column major
218  double val = ((*(averageData+(i*m_iTotalNumberChannels)+m_iChannelNumber))-offset) * dScaleY;
219 
220  //Cut plotting if six times bigger than m_iMaxHeigth
221  if(std::fabs(val) > 6*m_iMaxHeigth && m_bIsBad) {
222  qSamplePosition.setY(-(val/val) * m_iMaxHeigth); //(val/val) used to retrieve sign of val
223  qSamplePosition.setX(path.currentPosition().x()+1);
224  } else {
225  qSamplePosition.setY(-val);
226  qSamplePosition.setX(path.currentPosition().x()+1);
227  }
228 
229  path.lineTo(qSamplePosition);
230  }
231 
232  painter->drawPath(path);
233  }
234  }
235 }
236 
237 //=============================================================================================================
238 
239 void AverageSceneItem::paintStimLine(QPainter *painter)
240 {
241  if(m_lAverageData.size() == 0)
242  return;
243 
244  //Plot vertical and horizontal lines
245  QRectF boundingRect = this->boundingRect();
246  QPainterPath path = QPainterPath(QPointF(boundingRect.x(), boundingRect.y() + boundingRect.height()/2));
247 
248  int dsFactor = 1;
249  int totalCols = m_lAverageData.first().second.second;
250  totalCols / boundingRect.width()<1 ? dsFactor = 1 : dsFactor = totalCols / boundingRect.width();
251 
252  if(dsFactor == 0)
253  dsFactor = 1;
254 
255  QPen pen;
256  pen.setStyle(Qt::SolidLine);
257  pen.setColor(Qt::red);
258  pen.setWidthF(3);
259  painter->setPen(pen);
260 
261  //Stim line
262  path.moveTo(boundingRect.x() + std::abs(m_firstLastSample.first)/dsFactor, boundingRect.y());
263  path.lineTo(boundingRect.x() + std::abs(m_firstLastSample.first)/dsFactor, boundingRect.y() + boundingRect.height());
264 
265  //zero line
266  path.moveTo(boundingRect.x(), boundingRect.y() + boundingRect.height()/2);
267  path.lineTo(boundingRect.x() + m_lAverageData.first().second.second/dsFactor, boundingRect.y() + boundingRect.height()/2);
268 
269  painter->drawPath(path);
270 }
271 
272 //=============================================================================================================
273 
274 void AverageSceneItem::setDefaultColor(const QColor &viewColor)
275 {
276  m_colorDefault = viewColor;
277 }
278 
279 //=============================================================================================================
Old fiff_type declarations - replace them.
AverageSceneItem(const QString &channelName, int channelNumber, const QPointF &channelPosition, int channelKind, int channelUnit, const QColor &color=Qt::yellow)
DISPSHARED_EXPORT float getScalingValue(const QMap< qint32, float > &qMapChScaling, int iChannelKind, int iChannelUnit)
QMap< QString, QColor > m_qMapAverageColor
QList< QPair< QString, RowVectorPair > > m_lAverageData
void paintAveragePath(QPainter *painter)
QMap< qint32, float > m_scaleMap
Contains the declaration of the AverageSceneItem class.
QMap< QString, bool > m_qMapAverageActivation
void setDefaultColor(const QColor &viewColor)
void paintStimLine(QPainter *painter)
QPair< int, int > m_firstLastSample