MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
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
60using namespace DISPLIB;
61#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
62using namespace QtCharts;
63#endif
64
65//=============================================================================================================
66// DEFINE MEMBER METHODS
67//=============================================================================================================
68
69Spline::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
93void 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
179void 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
271void 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
297void 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
327const 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
345QVector3D 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}
Spline class declaration.
ColorMap class declaration.
static QRgb valueToColor(double v, const QString &sMap)
Definition colormap.h:688
QString m_colorMap
Definition spline.h:217
QSplineSeries * m_pSeries
Definition spline.h:210
void setThreshold(const QVector3D &vecThresholdValues)
Definition spline.cpp:179
int m_iMaximumFrequency
Definition spline.h:215
void mousePressEvent(QMouseEvent *event)
Definition spline.cpp:93
QLineSeries * m_pRightThreshold
Definition spline.h:213
Spline(QWidget *parent=0, const QString &title="Spline Histogram")
Definition spline.cpp:69
QVector3D m_vecReturnVector
Definition spline.h:218
Eigen::VectorXi m_vecResultExponentValues
Definition spline.h:188
QLineSeries * m_pMiddleThreshold
Definition spline.h:212
void updateThreshold(QLineSeries *lineSeries)
Definition spline.cpp:271
QVector3D correctionDisplayTrueValue(QVector3D vecOriginalValues, QString functionName)
Definition spline.cpp:345
void borderChanged(double leftThreshold, double middleThreshold, double rightThreshold)
QChart * m_pChart
Definition spline.h:209
void setColorMap(const QString &colorMap)
Definition spline.cpp:297
QLineSeries * m_pLeftThreshold
Definition spline.h:211
double m_dMaxAxisX
Definition spline.h:190
const QVector3D & getThreshold()
Definition spline.cpp:327
double m_dMinAxisX
Definition spline.h:189