MNE-CPP  0.1.9
A Framework for Electrophysiology
spline.h
Go to the documentation of this file.
1 //=============================================================================================================
34 #ifndef SPLINE_H
35 #define SPLINE_H
36 
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "../disp_global.h"
42 
43 //=============================================================================================================
44 // QT INCLUDES
45 //=============================================================================================================
46 
47 #include <QWidget>
48 #include <QtCharts/QChart>
49 #include <QtCharts/QSplineSeries>
50 #include <QVector3D>
51 
52 //=============================================================================================================
53 // EIGEN INCLUDES
54 //=============================================================================================================
55 
56 #include <Eigen/Core>
57 
58 //=============================================================================================================
59 // FORWARD DECLARATIONS
60 //=============================================================================================================
61 
62 class QMouseEvent;
63 
64 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
65 namespace QtCharts{
66  class QLineSeries;
67 }
68 #else
69 class QLineSeries;
70 #endif
71 
72 
73 //=============================================================================================================
74 // DEFINE NAMESPACE DISPLIB
75 //=============================================================================================================
76 
77 namespace DISPLIB
78 {
79 
80 //=============================================================================================================
81 // DISPLIB FORWARD DECLARATIONS
82 //=============================================================================================================
83 
84 //=============================================================================================================
89 class DISPSHARED_EXPORT Spline: public QWidget
90 {
91  Q_OBJECT
92 
93 public:
94  typedef QSharedPointer<Spline> SPtr;
95  typedef QSharedPointer<const Spline> ConstSPtr;
97  //=========================================================================================================
103  Spline(QWidget* parent = 0, const QString& title = "Spline Histogram");
104 
105  //=========================================================================================================
112  template<typename T>
113  void setData(const Eigen::Matrix<T, Eigen::Dynamic, 1>& matClassLimitData,
114  const Eigen::Matrix<int, Eigen::Dynamic, 1>& matClassFrequencyData);
115  template<typename T>
116  void setData(const Eigen::Matrix<T, 1, Eigen::Dynamic>& matClassLimitData,
117  const Eigen::Matrix<int, 1, Eigen::Dynamic>& matClassFrequencyData);
118 
119  //=========================================================================================================
126  template<typename T>
127  void updatePlot(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matClassLimitData,
128  const Eigen::VectorXi& matClassFrequencyData);
129 
130  //=========================================================================================================
136  void mousePressEvent(QMouseEvent *event);
137 
138  //=========================================================================================================
147  template<typename T>
148  void splitCoefficientAndExponent(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matClassLimitData,
149  int iClassAmount,
150  Eigen::VectorXd& vecCoefficientResults,
151  Eigen::VectorXi& vecExponentValues);
152 
153  //=========================================================================================================
159  void setThreshold(const QVector3D& vecThresholdValues);
160 
161  //=========================================================================================================
167  const QVector3D& getThreshold();
168 
169  //=========================================================================================================
177  QVector3D correctionDisplayTrueValue(QVector3D vecOriginalValues,
178  QString functionName);
179 
180  //=========================================================================================================
186  void setColorMap (const QString &colorMap);
187 
188  Eigen::VectorXi m_vecResultExponentValues;
189  double m_dMinAxisX;
190  double m_dMaxAxisX;
192 protected:
193  //=========================================================================================================
200 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
201  void updateThreshold (QtCharts::QLineSeries *lineSeries);
202  QtCharts::QChart* m_pChart;
203  QtCharts::QSplineSeries* m_pSeries;
204  QtCharts::QLineSeries* m_pLeftThreshold;
205  QtCharts::QLineSeries* m_pMiddleThreshold;
206  QtCharts::QLineSeries* m_pRightThreshold;
207 #else
208  void updateThreshold (QLineSeries *lineSeries);
209  QChart* m_pChart;
210  QSplineSeries* m_pSeries;
211  QLineSeries* m_pLeftThreshold;
212  QLineSeries* m_pMiddleThreshold;
213  QLineSeries* m_pRightThreshold;
214 #endif
216  QList<QVector3D> m_pReturnList;
217  QString m_colorMap;
218  QVector3D m_vecReturnVector;
220 signals:
221  //=========================================================================================================
229  void borderChanged(double leftThreshold, double middleThreshold, double rightThreshold);
230 };
231 
232 //=============================================================================================================
233 // INLINE DEFINITIONS
234 //=============================================================================================================
235 
236 template <typename T>
237 void Spline::setData(const Eigen::Matrix<T, Eigen::Dynamic, 1>& matClassLimitData,
238  const Eigen::Matrix<int, Eigen::Dynamic, 1>& matClassFrequencyData)
239 {
240  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> matrixName(matClassLimitData.rows(),1);
241  matrixName.col(0) = matClassLimitData;
242  this->updatePlot(matrixName, matClassFrequencyData);
243 }
244 
245 //=========================================================================================================
246 
247 template <typename T>
248 void Spline::setData(const Eigen::Matrix<T, 1, Eigen::Dynamic>& matClassLimitData,
249  const Eigen::Matrix<int, 1, Eigen::Dynamic>& matClassFrequencyData)
250 {
251  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> matrixName(1, matClassLimitData.cols());
252  matrixName.row(0) = matClassLimitData;
253  this->updatePlot(matrixName, matClassFrequencyData);
254 }
255 
256 //=========================================================================================================
257 
258 template<typename T>
259 void Spline::updatePlot(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matClassLimitData,
260  const Eigen::VectorXi& matClassFrequencyData)
261 {
262  Eigen::VectorXd resultDisplayValues;
263  int iClassAmount = matClassFrequencyData.rows();
264  this->splitCoefficientAndExponent (matClassLimitData, iClassAmount, resultDisplayValues, m_vecResultExponentValues);
265 
266  // Start of Qtchart histogram display
267  QString histogramExponent;
268  histogramExponent = "X-axis scale: 10e" + QString::number(m_vecResultExponentValues(0)); //used to tell the user the exponential scale used in the histogram
269  m_pSeries->setName(histogramExponent);
270  m_pSeries->clear();
271  m_pChart->removeSeries(m_pSeries);
272  m_pChart->removeSeries(m_pLeftThreshold); //create new series and then clear the plot and update with new data
273  m_pChart->removeSeries(m_pMiddleThreshold);
274  m_pChart->removeSeries(m_pRightThreshold);
275 
276  m_dMinAxisX = resultDisplayValues(0);
277  m_dMaxAxisX = resultDisplayValues(iClassAmount);
278  double classMark; //class mark is the middle point between lower and upper class limit
279  m_iMaximumFrequency = 0; //iMaximumFrequency used to create an intuitive histogram
280 
281  for (int ir = 0; ir < iClassAmount; ++ir)
282  {
283  classMark = (resultDisplayValues(ir) + resultDisplayValues(ir+1))/2 ;
284  m_pSeries->append(classMark, matClassFrequencyData(ir));
285  //std::cout << "Spline data points = " << classMark << ", " << matClassFrequencyData(ir) << std::endl;
286  if (matClassFrequencyData(ir) > m_iMaximumFrequency)
287  {
288  m_iMaximumFrequency = matClassFrequencyData(ir);
289  }
290  }
291 
292 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
293  m_pLeftThreshold = new QtCharts::QLineSeries();
294  m_pMiddleThreshold = new QtCharts::QLineSeries();
295  m_pRightThreshold = new QtCharts::QLineSeries();
296 #else
297  m_pLeftThreshold = new QLineSeries();
298  m_pMiddleThreshold = new QLineSeries();
299  m_pRightThreshold = new QLineSeries();
300 #endif
301 
302  m_pLeftThreshold->setName("left");
303  m_pMiddleThreshold->setName("middle");
304  m_pRightThreshold->setName("right");
305 
306  m_pChart->addSeries(m_pSeries);
307  m_pChart->legend()->setVisible(true);
308  m_pChart->legend()->setAlignment(Qt::AlignBottom);
309  m_pChart->createDefaultAxes();
310  m_pChart->axisX()->setRange(m_dMinAxisX, m_dMaxAxisX);
311 }
312 
313 //=============================================================================================================
314 
315 template <typename T>
316 void Spline::splitCoefficientAndExponent (const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& matClassLimitData,
317  int iClassAmount,
318  Eigen::VectorXd& vecCoefficientResults,
319  Eigen::VectorXi& vecExponentValues)
320 {
321  vecCoefficientResults.resize(iClassAmount + 1);
322  vecExponentValues.resize(iClassAmount + 1);
323  double originalValue(0.0),
324  limitDisplayValue(0.0),
325  doubleExponentValue(0.0);
326  int limitExponentValue(0);
327  for (int ir = 0; ir <= iClassAmount; ++ir)
328  {
329  originalValue = matClassLimitData(ir);
330  if (originalValue == 0.0) //mechanism to guard against evaluation of log(0.0) which is infinity
331  {
332  doubleExponentValue = 0.0;
333  }
334 
335  else
336  {
337  doubleExponentValue = log10(std::fabs(originalValue)); //return the exponent value in double
338  }
339 
340  limitExponentValue = round(doubleExponentValue); //round the exponent value to the nearest signed integer
341  limitDisplayValue = originalValue * (pow(10,-(limitExponentValue))); //display value is derived from multiplying class limit with inverse 10 to the power of negative exponent
342  vecCoefficientResults(ir) = limitDisplayValue; //append the display value to the return vector
343  vecExponentValues(ir) = limitExponentValue; //append the exponent value to the return vector
344  }
345 
346  int lowestExponentValue{0},
347  highestExponentValue{0};
348 
349  for (int ir = 0; ir <= iClassAmount; ++ir)
350  {
351  if (vecExponentValues(ir) < lowestExponentValue)
352  {
353  lowestExponentValue = vecExponentValues(ir); //find lowest exponent value to normalize display values for negative exponent
354  }
355  if (vecExponentValues(ir) > highestExponentValue) //find highest exponent value to normalize display values for positive exponent
356  {
357  highestExponentValue = vecExponentValues(ir);
358  }
359  }
360 
361  if (highestExponentValue > 0)
362  {
363  for (int ir = 0; ir <= iClassAmount; ++ir)
364  {
365  while (vecExponentValues(ir) < highestExponentValue) //normalize the values by multiplying the display value by 10 and reducing the exponentValue by 1 until exponentValue reach the lowestExponentValue
366  {
367  vecCoefficientResults(ir) = vecCoefficientResults(ir) / 10;
368  vecExponentValues(ir)++;
369  }
370  }
371  }
372 
373  if (lowestExponentValue < 0)
374  {
375  for (int ir = 0; ir <= iClassAmount; ++ir)
376  {
377  while (vecExponentValues(ir) > lowestExponentValue)
378  {
379  vecCoefficientResults(ir) = vecCoefficientResults(ir) * 10;
380  vecExponentValues(ir)--;
381  }
382  }
383  }
384 }
385 } // NAMESPACE
386 
387 #endif // SPLINE_H
DISPLIB::Spline::m_pSeries
QSplineSeries * m_pSeries
Definition: spline.h:210
DISPSHARED_EXPORT
#define DISPSHARED_EXPORT
Definition: disp_global.h:55
DISPLIB::Spline::updatePlot
void updatePlot(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &matClassLimitData, const Eigen::VectorXi &matClassFrequencyData)
Definition: spline.h:259
DISPLIB::Spline::m_dMaxAxisX
double m_dMaxAxisX
Definition: spline.h:190
DISPLIB::Spline::m_pChart
QChart * m_pChart
Definition: spline.h:209
DISPLIB::Spline
Spline class for histogram display using Qtcharts/QSpline.
Definition: spline.h:89
DISPLIB::Spline::m_pRightThreshold
QLineSeries * m_pRightThreshold
Definition: spline.h:213
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::SPtr
QSharedPointer< Spline > SPtr
Definition: spline.h:94
DISPLIB::Spline::m_dMinAxisX
double m_dMinAxisX
Definition: spline.h:189
DISPLIB::Spline::setData
void setData(const Eigen::Matrix< T, Eigen::Dynamic, 1 > &matClassLimitData, const Eigen::Matrix< int, Eigen::Dynamic, 1 > &matClassFrequencyData)
Definition: spline.h:237
DISPLIB::Spline::m_iMaximumFrequency
int m_iMaximumFrequency
Definition: spline.h:215
DISPLIB::Spline::m_vecReturnVector
QVector3D m_vecReturnVector
Definition: spline.h:218
DISPLIB::Spline::m_colorMap
QString m_colorMap
Definition: spline.h:217
DISPLIB::Spline::splitCoefficientAndExponent
void splitCoefficientAndExponent(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &matClassLimitData, int iClassAmount, Eigen::VectorXd &vecCoefficientResults, Eigen::VectorXi &vecExponentValues)
Definition: spline.h:316
DISPLIB::Spline::ConstSPtr
QSharedPointer< const Spline > ConstSPtr
Definition: spline.h:95
DISPLIB::Spline::m_pReturnList
QList< QVector3D > m_pReturnList
Definition: spline.h:216