MNE-CPP  0.1.9
A Framework for Electrophysiology
filterplotscene.cpp
Go to the documentation of this file.
1 //=============================================================================================================
36 //=============================================================================================================
37 // INCLUDES
38 //=============================================================================================================
39 
40 #include "filterplotscene.h"
41 
42 //=============================================================================================================
43 // QT INCLUDES
44 //=============================================================================================================
45 
46 #include <QGraphicsPathItem>
47 #include <QGraphicsView>
48 #include <QDebug>
49 
50 //=============================================================================================================
51 // EIGEN INCLUDES
52 //=============================================================================================================
53 
54 //=============================================================================================================
55 // USED NAMESPACES
56 //=============================================================================================================
57 
58 using namespace DISPLIB;
59 using namespace Eigen;
60 using namespace RTPROCESSINGLIB;
61 
62 //=============================================================================================================
63 // DEFINE MEMBER METHODS
64 //=============================================================================================================
65 
66 FilterPlotScene::FilterPlotScene(QGraphicsView *view, QObject *parent)
67 : LayoutScene(view, parent)
68 , m_pGraphicsItemPath(new QGraphicsPathItem())
69 , m_iScalingFactor(5)
70 , m_iNumberHorizontalLines(4)
71 , m_iNumberVerticalLines(3)
72 , m_iAxisTextSize(24)
73 , m_iDiagramMarginsHoriz(5)
74 , m_iDiagramMarginsVert(5)
75 , m_iCutOffLow(5)
76 , m_iCutOffHigh(40)
77 , m_iCutOffMarkerWidth(3)
78 , m_iPlotLength(0)
79 {
81 }
82 
83 //=============================================================================================================
84 
85 void FilterPlotScene::updateFilter(const FilterKernel& operatorFilter,
86  int samplingFreq,
87  int cutOffLow,
88  int cutOffHigh)
89 {
90  if(operatorFilter.getCoefficients().cols() == 0)
91  return;
92 
93  m_pCurrentFilter = operatorFilter;
94 
95  //set member variables
96  m_iCutOffLow = cutOffLow;
97  m_iCutOffHigh = cutOffHigh;
98 
99  //Clear the scene
100  this->clear();
101 
102  QWidget * pQwidgetty(dynamic_cast<QWidget*>(parent()));
103  m_cPenColor = pQwidgetty->palette().text().color();
104 
105  //Plot newly set filter. Needs to be called before plotMagnitudeDiagram() because m_iPlotLength is set in plotFilterFrequencyResponse()
107 
108  //Plot the magnitude diagram
109  plotMagnitudeDiagram(samplingFreq, operatorFilter.getName());
110 }
111 
112 //=============================================================================================================
113 
115  const QString& filtername)
116 {
117  //Get row vector with filter coefficients
118  int numberCoeff = m_iPlotLength;
119 
120 // RowVectorXcd coefficientsAFreq = m_pCurrentFilter.m_vecFftCoeff;
121 // if(coefficientsAFreq.cols() > 2000) {//if to large downsample
122 // int dsFactor = coefficientsAFreq.cols()/2000;
123 // numberCoeff = coefficientsAFreq.cols()/dsFactor;
124 // } else {
125 // numberCoeff = coefficientsAFreq.cols();
126 // }
127 
128  int fMax = samplingFreq/2; //nyquist frequency
129 
130  addRect(-m_iDiagramMarginsHoriz,
132  numberCoeff+(m_iDiagramMarginsHoriz*2),
134 
135  //Plot filter name on top
136  QGraphicsTextItem * text = addText(filtername, QFont("Times", m_iAxisTextSize));
137  text->setPos((numberCoeff+(m_iDiagramMarginsHoriz*2))/3.2,-70);
138  text->setDefaultTextColor(m_cPenColor);
139 
140 
141  //HORIZONTAL
142  //Draw horizontal lines
143  QPen pen(Qt::DotLine);
144  pen.setColor(m_cPenColor);
145  for(int i = 1; i <= m_iNumberHorizontalLines; i++)
146  addLine(-m_iDiagramMarginsHoriz,
148  numberCoeff + m_iDiagramMarginsHoriz,
150  pen);
151 
152  //Draw vertical axis texts - db magnitude
153  for(int i = 0; i <= m_iNumberHorizontalLines+1; i++) {
154  QGraphicsTextItem * text = addText(QString("-%1 db").arg(QString().number(i * m_iMaxMagnitude/(m_iScalingFactor*(m_iNumberHorizontalLines+1)),'g',3)),
155  QFont("Times", m_iAxisTextSize));
156  text->setPos(-text->boundingRect().width() - m_iAxisTextSize/2,
157  (i * (m_iMaxMagnitude/(m_iNumberHorizontalLines+1))) - (text->boundingRect().height()/2) - m_iDiagramMarginsVert);
158  text->setDefaultTextColor(m_cPenColor);
159  }
160 
161  //VERTICAL
162  //Draw vertical lines
163  double length = double(numberCoeff) / double(m_iNumberVerticalLines+1);
164  for(int i = 1; i<=m_iNumberVerticalLines; i++)
165  addLine(i*length - m_iDiagramMarginsHoriz,
167  i*length - m_iDiagramMarginsHoriz,
169  pen);
170 
171  //Draw horizontal axis texts - Hz frequency
172  for(int i = 0; i <= m_iNumberVerticalLines+1; i++) {
173  QGraphicsTextItem * text = addText(QString("%1 Hz").arg(i*(fMax/(m_iNumberVerticalLines+1))),
174  QFont("Times", m_iAxisTextSize));
175  text->setPos(i * length - m_iDiagramMarginsHoriz - (text->boundingRect().width()/2),
176  m_iMaxMagnitude + (text->boundingRect().height()/2));
177  text->setDefaultTextColor(m_cPenColor);
178  }
179 
180  //Plot lower higher cut off frequency
181  double pos = 0;
182  switch(FilterKernel::m_filterTypes.indexOf(m_pCurrentFilter.getFilterType())) {
183  case 0://LPF
184  pos = ((double)m_iCutOffLow / (double)fMax) * numberCoeff;
185  addLine(pos - m_iDiagramMarginsHoriz,
189  QPen(Qt::red, m_iCutOffMarkerWidth));
190  break;
191 
192  case 1://HPF
193  pos = ((double)m_iCutOffHigh / (double)fMax) * numberCoeff;
194  addLine(pos - m_iDiagramMarginsHoriz,
198  QPen(Qt::red, m_iCutOffMarkerWidth));
199  break;
200 
201  case 2://BPF
202  pos = ((double)m_iCutOffLow / (double)fMax) * numberCoeff;
203  addLine(pos - m_iDiagramMarginsHoriz,
207  QPen(Qt::red, m_iCutOffMarkerWidth));
208 
209  pos = ((double)m_iCutOffHigh / (double)fMax) * numberCoeff;
210  addLine(pos - m_iDiagramMarginsHoriz,
214  QPen(Qt::red, m_iCutOffMarkerWidth));
215  break;
216  }
217 }
218 
219 //=============================================================================================================
220 
222 {
223  //Get row vector with filter coefficients and norm to 1
224  RowVectorXcd coefficientsAFreq = m_pCurrentFilter.getFftCoefficients();
225 
226  float numberCoeff = coefficientsAFreq.cols();
227  float dsFactor = numberCoeff/m_qvView->width();
228 
229  double max = 0.0;
230  for(int i = 0; i<coefficientsAFreq.cols(); i++) {
231  if(std::abs(coefficientsAFreq(i)) > max) {
232  max = std::abs(coefficientsAFreq(i));
233  }
234  }
235 
236  coefficientsAFreq = coefficientsAFreq / max;
237 
238  //Create painter path
239  QPainterPath path;
240  double y = -20 * log10(std::abs(coefficientsAFreq(0))) * m_iScalingFactor; //-1 because we want to plot upwards
241  if(y > m_iMaxMagnitude) {
242  y = m_iMaxMagnitude;
243  }
245 
246  path.moveTo(-m_iDiagramMarginsVert, y); //convert to db
247 
248  for(int i = 0; i < numberCoeff; i++) {
249  y = -20 * log10(std::abs(coefficientsAFreq(i))) * m_iScalingFactor; //-1 because we want to plot upwards
250  if(y > m_iMaxMagnitude) {
251  y = m_iMaxMagnitude;
252  }
253 
255  if(dsFactor < 1) {
256  path.lineTo(path.currentPosition().x()+(1/dsFactor),y);
257  } else {
258  path.lineTo(path.currentPosition().x()+1,y);
259  }
260  }
261 
262  m_iPlotLength = path.currentPosition().x();
263 
264  QPen pen;
265  pen.setColor(m_cPenColor);
266  pen.setWidth(2);
267 
268  //Clear old and plot new filter path
269  m_pGraphicsItemPath = addPath(path, pen);
270 }
271 
272 //=============================================================================================================
273 
QGraphicsView * m_qvView
Definition: layoutscene.h:175
Contains the declaration of the FilterPlotScene class.
The FilterKernel class provides methods to create/design a FIR filter kernel.
Definition: filterkernel.h:132
QGraphicsPathItem * m_pGraphicsItemPath
FilterPlotScene(QGraphicsView *view, QObject *parent=0)
void updateFilter(const RTPROCESSINGLIB::FilterKernel &operatorFilter, int samplingFreq, int cutOffLow, int cutOffHigh)
void plotMagnitudeDiagram(int samplingFreq, const QString &filtername=QString())
The LayoutScene class provides a reimplemented QGraphicsScene for 2D layout plotting. This class handles all the user interaction features (subclass in order to use).
Definition: layoutscene.h:81
RTPROCESSINGLIB::FilterKernel m_pCurrentFilter