MNE-CPP  0.1.9
A Framework for Electrophysiology
spline.cpp
Go to the documentation of this file.
1 //=============================================================================================================
35 //=============================================================================================================
36 // INCLUDES
37 //=============================================================================================================
38 
39 #include "spline.h"
40 
41 #include "helpers/colormap.h"
42 
43 //=============================================================================================================
44 // QT INCLUDES
45 //=============================================================================================================
46 
47 #include <QGridLayout>
48 #include <QtCharts/QLegendMarker>
49 #include <QtCharts/QChartView>
50 #include <QDebug>
51 
52 //=============================================================================================================
53 // EIGEN INCLUDES
54 //=============================================================================================================
55 
56 //=============================================================================================================
57 // USED NAMESPACES
58 //=============================================================================================================
59 
60 using namespace DISPLIB;
61 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
62 using namespace QtCharts;
63 #endif
64 
65 //=============================================================================================================
66 // DEFINE MEMBER METHODS
67 //=============================================================================================================
68 
69 Spline::Spline(QWidget* parent, const QString& title)
70 : QWidget(parent)
71 , m_dMinAxisX(0)
72 , m_dMaxAxisX(0)
73 , m_pLeftThreshold(new QLineSeries())
74 , m_pMiddleThreshold(new QLineSeries())
75 , m_pRightThreshold(new QLineSeries())
76 , m_iMaximumFrequency(0)
77 {
78  Q_UNUSED(title)
79  m_pChart = new QChart();
80  //m_pChart->setTitle(title);
81  m_pChart->setAnimationOptions(QChart::SeriesAnimations);
82  m_pChart->setAcceptHoverEvents(false);
83  m_pSeries = new QSplineSeries();
84  QChartView *chartView = new QChartView(m_pChart);
85  chartView->setRenderHint(QPainter::Antialiasing);
86  QGridLayout* layout = new QGridLayout();
87  layout->addWidget(chartView, 0, 0);
88  this->setLayout(layout);
89 }
90 
91 //=============================================================================================================
92 
93 void Spline::mousePressEvent(QMouseEvent *event)
94 {
95  if (m_pSeries->count() == 0) //protect integrity of the histogram widget in case series contain no data values
96  {
97  qDebug() << "Data set not found."; //do nothing
98  }
99 
100  else
101  {
102  QXYSeries *shadowSeries = qobject_cast<QXYSeries *>(sender());
103  QLineSeries *verticalLine = new QLineSeries();
104  QPointF point = event->pos();
105  QPointF pointY = point;
106  pointY.setX(m_dMinAxisX);
107  pointY.setY(pointY.y()-10.5); //-10.5 needed to correctly position the line at mouse position
108  point.setX(point.x()-10.5);
109  point.setY(0);
110 
111  QPointF localX = m_pChart->mapToValue(point, shadowSeries);
112  QPointF localY = m_pChart->mapToValue(pointY, shadowSeries);
113  verticalLine->append(localX.x(), 0);
114  verticalLine->append(localX.x(), m_iMaximumFrequency);
115  double boundaryX = double(localX.x()); //casting localX.x() from float to double for comparison with minAxisX and maxAxisX
116  double boundaryY = double(localY.y()); //casting localY.y() from float to double for comparison with 0 and the maximum frequency
117 
118  if((boundaryX >= float(m_dMinAxisX)) && (boundaryX <= float(m_dMaxAxisX))) //this condition ensures that threshold lines can only be created within the boundary of the x-axis
119  {
120  if((boundaryY >= 0.0) && (boundaryY <= float(m_iMaximumFrequency))) // this condition ensures that threshold lines can only be created within the boundary of the y-axis
121  {
122  QVector<QPointF> middlePoint = m_pMiddleThreshold->pointsVector(); //Point values need to be updated before tested and displayed on the widget
123  QVector<QPointF> rightPoint = m_pRightThreshold->pointsVector();
124  QVector<QPointF> leftPoint = m_pLeftThreshold->pointsVector();
125 
126  double emitLeft = (leftPoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
127  double emitMiddle = (middlePoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
128  double emitRight = (rightPoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
129 
130  if (event->buttons() == Qt::LeftButton)
131  {
132  leftPoint = verticalLine->pointsVector();
133  if((leftPoint[0].x() < middlePoint[0].x()) && (leftPoint[0].x() < rightPoint[0].x()))
134  {
135  m_pChart->removeSeries(m_pLeftThreshold);
136  m_pLeftThreshold = verticalLine;
137  m_pLeftThreshold->setName("left");
139  emitLeft = (leftPoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
140  emit borderChanged(emitLeft, emitMiddle, emitRight);
141  }
142  }
143 
144  if (event->buttons() == Qt::MiddleButton)
145  {
146  middlePoint = verticalLine->pointsVector();
147  if((middlePoint[0].x() > leftPoint[0].x()) && (middlePoint[0].x() < rightPoint[0].x()))
148  {
149  m_pChart->removeSeries(m_pMiddleThreshold);
150  m_pMiddleThreshold = verticalLine;
151  m_pMiddleThreshold->setName("middle");
153  emitMiddle = (middlePoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
154  emit borderChanged(emitLeft, emitMiddle, emitRight);
155  }
156  }
157 
158  if (event->buttons() == Qt::RightButton)
159  {
160  rightPoint = verticalLine->pointsVector();
161  if((rightPoint[0].x() > leftPoint[0].x()) && (rightPoint[0].x() > middlePoint[0].x()))
162  {
163  m_pChart->removeSeries(m_pRightThreshold);
164  m_pRightThreshold = verticalLine;
165  m_pRightThreshold->setName("right");
167  emitRight = (rightPoint[0].x() * (pow(10, m_vecResultExponentValues[0])));
168  emit borderChanged(emitLeft, emitMiddle, emitRight);
169  }
170  }
171  }
172  }
174  }
175 }
176 
177 //=============================================================================================================
178 
179 void Spline::setThreshold(const QVector3D& vecThresholdValues)
180 {
181  float leftThresholdValue = vecThresholdValues.x();
182  float middleThresholdValue = vecThresholdValues.y();
183  float rightThresholdValue = vecThresholdValues.z();
184 
185  QVector3D correctedVectorThreshold = correctionDisplayTrueValue(vecThresholdValues, "up");
186 
187  if (m_pSeries->count() == 0) //protect integrity of the histogram widget in case series contain no data values
188  {
189  qDebug() << "Data set not found.";
190  }
191 
192 // the condition below tests the threshold values given and ensures that all three must be within minAxisX and maxAxisX otherwise they will be given either minAxisX or maxAxisX value
193  else if (correctedVectorThreshold.x() < m_dMinAxisX || correctedVectorThreshold.y() < m_dMinAxisX || correctedVectorThreshold.z() < m_dMinAxisX || correctedVectorThreshold.x() > m_dMaxAxisX || correctedVectorThreshold.y() > m_dMaxAxisX || correctedVectorThreshold.z() > m_dMaxAxisX)
194  {
195  qDebug() << "One or more of the values given are out of the minimum and maximum range. Changed to default thresholds.";
196  leftThresholdValue = 1.01 * m_dMinAxisX;
197  middleThresholdValue = (m_dMinAxisX + m_dMaxAxisX) / 2;
198  rightThresholdValue = 0.99 * m_dMaxAxisX;
199  }
200  else
201  {
202  if ((correctedVectorThreshold.x() < correctedVectorThreshold.y()) && (correctedVectorThreshold.x() < correctedVectorThreshold.z()))
203  {
204  leftThresholdValue = correctedVectorThreshold.x();
205  if(correctedVectorThreshold.y() < correctedVectorThreshold.z())
206  {
207  middleThresholdValue = correctedVectorThreshold.y();
208  rightThresholdValue = correctedVectorThreshold.z();
209  }
210  else
211  {
212  middleThresholdValue = correctedVectorThreshold.z();
213  rightThresholdValue = correctedVectorThreshold.y();
214  }
215  }
216  if ((correctedVectorThreshold.y() < correctedVectorThreshold.x()) && (correctedVectorThreshold.y() < correctedVectorThreshold.z()))
217  {
218  leftThresholdValue = correctedVectorThreshold.y();
219 
220  if(correctedVectorThreshold.x() < correctedVectorThreshold.z())
221  {
222  middleThresholdValue = correctedVectorThreshold.x();
223  rightThresholdValue = correctedVectorThreshold.z();
224  }
225  else
226  {
227  middleThresholdValue = correctedVectorThreshold.z();
228  rightThresholdValue = correctedVectorThreshold.x();
229  }
230  }
231  if ((correctedVectorThreshold.z() < correctedVectorThreshold.x()) && (correctedVectorThreshold.z() < correctedVectorThreshold.y()))
232  {
233  leftThresholdValue = correctedVectorThreshold.z();
234 
235  if(correctedVectorThreshold.x() < correctedVectorThreshold.y())
236  {
237  middleThresholdValue = correctedVectorThreshold.x();
238  rightThresholdValue = correctedVectorThreshold.y();
239  }
240  else
241  {
242  middleThresholdValue = correctedVectorThreshold.y();
243  rightThresholdValue = correctedVectorThreshold.x();
244  }
245  }
246  }
247 
248  QPointF leftThresholdPoint;
249  QPointF middleThresholdPoint;
250  QPointF rightThresholdPoint;
251 
252  leftThresholdPoint.setX(leftThresholdValue);
253  middleThresholdPoint.setX(middleThresholdValue);
254  rightThresholdPoint.setX(rightThresholdValue);
255 
256  m_pLeftThreshold->append(leftThresholdPoint.x(), 0);
257  m_pLeftThreshold->append(leftThresholdPoint.x(), m_iMaximumFrequency);
258  m_pMiddleThreshold->append(middleThresholdPoint.x(), 0);
259  m_pMiddleThreshold->append(middleThresholdPoint.x(), m_iMaximumFrequency);
260  m_pRightThreshold->append(rightThresholdPoint.x(), 0);
261  m_pRightThreshold->append(rightThresholdPoint.x(), m_iMaximumFrequency);
262 
267 }
268 
269 //=============================================================================================================
270 
271 void Spline::updateThreshold(QLineSeries* lineSeries)
272 {
273  if (lineSeries->name() == "left")
274  {
275  lineSeries->setColor("red");
276  }
277  else if (lineSeries->name() == "middle")
278  {
279  lineSeries->setColor("green");
280  }
281  else if (lineSeries->name() == "right")
282  {
283  lineSeries->setColor("blue");
284  }
285  else
286  {
287  qDebug()<< "Error: lineSeries->name() is not 'left', 'middle' or 'right'.";
288  }
289  lineSeries->setVisible(true);
290  m_pChart->addSeries(lineSeries);
291  m_pChart->legend()->markers().at(m_pChart->legend()->markers().size()-1)->setVisible(false);
292  m_pChart->createDefaultAxes();
293 }
294 
295 //=============================================================================================================
296 
297 void Spline::setColorMap(const QString& colorMap)
298 {
299  m_colorMap = colorMap;
300  double leftThresholdValue = (m_pLeftThreshold->at(0).x())/ m_dMaxAxisX;
301  double middleThresholdValue = (m_pMiddleThreshold->at(0).x())/ m_dMaxAxisX;
302  double rightThresholdValue = (m_pRightThreshold->at(0).x())/ m_dMaxAxisX;
303  int stepsNumber = 25;
304  double stepsSizeLeftMiddle = (middleThresholdValue - leftThresholdValue) / stepsNumber;
305  double stepsSizeMiddleRight = (rightThresholdValue - middleThresholdValue) / stepsNumber;
306  QLinearGradient plotAreaGradient;
307  plotAreaGradient.setStart(QPointF(0, 0));
308  plotAreaGradient.setFinalStop(QPointF(1, 0));
309 
310  plotAreaGradient.setColorAt(leftThresholdValue, ColorMap::valueToColor(0.0, colorMap));
311 
312  for (int i = 1; i < stepsNumber; ++i)
313  {
314  plotAreaGradient.setColorAt(leftThresholdValue + (stepsSizeLeftMiddle * i), ColorMap::valueToColor((double)i * (0.5 / (double)stepsNumber), colorMap));
315  plotAreaGradient.setColorAt(middleThresholdValue + (stepsSizeMiddleRight * i), ColorMap::valueToColor((double)0.5 + (i * (0.5 / (double)stepsNumber)), colorMap));
316  }
317  plotAreaGradient.setColorAt(rightThresholdValue, ColorMap::valueToColor(1.0, colorMap));
318 
319  // Customize plot area background
320  plotAreaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
321  m_pChart->setPlotAreaBackgroundBrush(plotAreaGradient);
322  m_pChart->setPlotAreaBackgroundVisible(true);
323 }
324 
325 //=============================================================================================================
326 
327 const QVector3D& Spline::getThreshold()
328 {
329  QVector<QPointF> middlePoint = m_pMiddleThreshold->pointsVector(); //Point values need to be updated before tested and displayed on the widget
330  QVector<QPointF> rightPoint = m_pRightThreshold->pointsVector();
331  QVector<QPointF> leftPoint = m_pLeftThreshold->pointsVector();
332  float emitLeft = leftPoint[0].x();
333  float emitMiddle = middlePoint[0].x();
334  float emitRight = rightPoint[0].x();
335  QVector3D originalVector;
336  originalVector.setX(emitLeft);
337  originalVector.setY(emitMiddle);
338  originalVector.setZ(emitRight);
339  m_vecReturnVector = correctionDisplayTrueValue(originalVector, "down");
340  return m_vecReturnVector;
341 }
342 
343 //=============================================================================================================
344 
345 QVector3D Spline::correctionDisplayTrueValue(QVector3D vecOriginalValues, QString upOrDown)
346 {
347  QVector3D returnCorrectedVector;
348 
349  if(m_vecResultExponentValues.rows() > 0) {
350  int exponent;
351  if (upOrDown == "up")
352  {
353  if (m_vecResultExponentValues[0] < 0)
354  {
355  exponent = std::abs(m_vecResultExponentValues[0]);
356  }
357  else if (m_vecResultExponentValues[0] > 0)
358  {
359  exponent = -(std::abs(m_vecResultExponentValues[0]));
360  }
361  else
362  {
363  exponent = 0;
364  }
365  }
366  else if (upOrDown == "down")
367  {
368  if (m_vecResultExponentValues[0] < 0)
369  {
370  exponent = -(std::abs(m_vecResultExponentValues[0]));
371  }
372  else if (m_vecResultExponentValues[0] > 0)
373  {
374  exponent = std::abs(m_vecResultExponentValues[0]);
375  }
376  else
377  {
378  exponent = 0;
379  }
380  }
381  else
382  {
383  qDebug() << "Spline::correctionDisplayTrueValue error.";
384  }
385 
386  returnCorrectedVector.setX(vecOriginalValues.x() * (pow(10, exponent)));
387  returnCorrectedVector.setY(vecOriginalValues.y() * (pow(10, exponent)));
388  returnCorrectedVector.setZ(vecOriginalValues.z() * (pow(10, exponent)));
389  }
390 
391  return returnCorrectedVector;
392 }
DISPLIB::Spline::Spline
Spline(QWidget *parent=0, const QString &title="Spline Histogram")
Definition: spline.cpp:69
DISPLIB::Spline::m_pSeries
QSplineSeries * m_pSeries
Definition: spline.h:210
DISPLIB::Spline::borderChanged
void borderChanged(double leftThreshold, double middleThreshold, double rightThreshold)
DISPLIB::Spline::m_dMaxAxisX
double m_dMaxAxisX
Definition: spline.h:190
DISPLIB::Spline::m_pChart
QChart * m_pChart
Definition: spline.h:209
DISPLIB::Spline::m_pRightThreshold
QLineSeries * m_pRightThreshold
Definition: spline.h:213
DISPLIB::ColorMap::valueToColor
static QRgb valueToColor(double v, const QString &sMap)
Definition: colormap.h:688
DISPLIB::Spline::m_pMiddleThreshold
QLineSeries * m_pMiddleThreshold
Definition: spline.h:212
DISPLIB::Spline::m_vecResultExponentValues
Eigen::VectorXi m_vecResultExponentValues
Definition: spline.h:188
DISPLIB::Spline::m_pLeftThreshold
QLineSeries * m_pLeftThreshold
Definition: spline.h:211
DISPLIB::Spline::mousePressEvent
void mousePressEvent(QMouseEvent *event)
Definition: spline.cpp:93
DISPLIB::Spline::m_dMinAxisX
double m_dMinAxisX
Definition: spline.h:189
DISPLIB::Spline::updateThreshold
void updateThreshold(QLineSeries *lineSeries)
Definition: spline.cpp:271
DISPLIB::Spline::m_iMaximumFrequency
int m_iMaximumFrequency
Definition: spline.h:215
DISPLIB::Spline::setColorMap
void setColorMap(const QString &colorMap)
Definition: spline.cpp:297
DISPLIB::Spline::getThreshold
const QVector3D & getThreshold()
Definition: spline.cpp:327
spline.h
Spline class declaration.
DISPLIB::Spline::m_vecReturnVector
QVector3D m_vecReturnVector
Definition: spline.h:218
DISPLIB::Spline::setThreshold
void setThreshold(const QVector3D &vecThresholdValues)
Definition: spline.cpp:179
DISPLIB::Spline::correctionDisplayTrueValue
QVector3D correctionDisplayTrueValue(QVector3D vecOriginalValues, QString functionName)
Definition: spline.cpp:345
DISPLIB::Spline::m_colorMap
QString m_colorMap
Definition: spline.h:217
colormap.h
ColorMap class declaration.