MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
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
58using namespace DISPLIB;
59using namespace Eigen;
60using namespace RTPROCESSINGLIB;
61
62//=============================================================================================================
63// DEFINE MEMBER METHODS
64//=============================================================================================================
65
66FilterPlotScene::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
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 //HORIZONTAL
141 //Draw horizontal lines
142 QPen pen(Qt::DotLine);
143 pen.setColor(m_cPenColor);
144 for(int i = 1; i <= m_iNumberHorizontalLines; i++)
145 addLine(-m_iDiagramMarginsHoriz,
147 numberCoeff + m_iDiagramMarginsHoriz,
149 pen);
150
151 //Draw vertical axis texts - db magnitude
152 for(int i = 0; i <= m_iNumberHorizontalLines+1; i++) {
153 QGraphicsTextItem * text = addText(QString("-%1 db").arg(QString().number(i * m_iMaxMagnitude/(m_iScalingFactor*(m_iNumberHorizontalLines+1)),'g',3)),
154 QFont("Times", m_iAxisTextSize));
155 text->setPos(-text->boundingRect().width() - m_iAxisTextSize/2,
156 (i * (m_iMaxMagnitude/(m_iNumberHorizontalLines+1))) - (text->boundingRect().height()/2) - m_iDiagramMarginsVert);
157 text->setDefaultTextColor(m_cPenColor);
158 }
159
160 //VERTICAL
161 //Draw vertical lines
162 double length = double(numberCoeff) / double(m_iNumberVerticalLines+1);
163 for(int i = 1; i<=m_iNumberVerticalLines; i++)
164 addLine(i*length - m_iDiagramMarginsHoriz,
166 i*length - m_iDiagramMarginsHoriz,
168 pen);
169
170 //Draw horizontal axis texts - Hz frequency
171 for(int i = 0; i <= m_iNumberVerticalLines+1; i++) {
172 QGraphicsTextItem * text = addText(QString("%1 Hz").arg(i*(fMax/(m_iNumberVerticalLines+1))),
173 QFont("Times", m_iAxisTextSize));
174 text->setPos(i * length - m_iDiagramMarginsHoriz - (text->boundingRect().width()/2),
175 m_iMaxMagnitude + (text->boundingRect().height()/2));
176 text->setDefaultTextColor(m_cPenColor);
177 }
178
179 //Plot lower higher cut off frequency
180 double pos = 0;
181 switch(FilterKernel::m_filterTypes.indexOf(m_pCurrentFilter.getFilterType())) {
182 case 0://LPF
183 pos = ((double)m_iCutOffLow / (double)fMax) * numberCoeff;
184 addLine(pos - m_iDiagramMarginsHoriz,
188 QPen(Qt::red, m_iCutOffMarkerWidth));
189 break;
190
191 case 1://HPF
192 pos = ((double)m_iCutOffHigh / (double)fMax) * numberCoeff;
193 addLine(pos - m_iDiagramMarginsHoriz,
197 QPen(Qt::red, m_iCutOffMarkerWidth));
198 break;
199
200 case 2://BPF
201 pos = ((double)m_iCutOffLow / (double)fMax) * numberCoeff;
202 addLine(pos - m_iDiagramMarginsHoriz,
206 QPen(Qt::red, m_iCutOffMarkerWidth));
207
208 pos = ((double)m_iCutOffHigh / (double)fMax) * numberCoeff;
209 addLine(pos - m_iDiagramMarginsHoriz,
213 QPen(Qt::red, m_iCutOffMarkerWidth));
214 break;
215 }
216}
217
218//=============================================================================================================
219
221{
222 //Get row vector with filter coefficients and norm to 1
223 RowVectorXcd coefficientsAFreq = m_pCurrentFilter.getFftCoefficients();
224
225 float numberCoeff = coefficientsAFreq.cols();
226 float dsFactor = numberCoeff/m_qvView->width();
227
228 double max = 0.0;
229 for(int i = 0; i<coefficientsAFreq.cols(); i++) {
230 if(std::abs(coefficientsAFreq(i)) > max) {
231 max = std::abs(coefficientsAFreq(i));
232 }
233 }
234
235 coefficientsAFreq = coefficientsAFreq / max;
236
237 //Create painter path
238 QPainterPath path;
239 double y = -20 * log10(std::abs(coefficientsAFreq(0))) * m_iScalingFactor; //-1 because we want to plot upwards
240 if(y > m_iMaxMagnitude) {
241 y = m_iMaxMagnitude;
242 }
244
245 path.moveTo(-m_iDiagramMarginsVert, y); //convert to db
246
247 for(int i = 0; i < numberCoeff; i++) {
248 y = -20 * log10(std::abs(coefficientsAFreq(i))) * m_iScalingFactor; //-1 because we want to plot upwards
249 if(y > m_iMaxMagnitude) {
250 y = m_iMaxMagnitude;
251 }
252
254 if(dsFactor < 1) {
255 path.lineTo(path.currentPosition().x()+(1/dsFactor),y);
256 } else {
257 path.lineTo(path.currentPosition().x()+1,y);
258 }
259 }
260
261 m_iPlotLength = path.currentPosition().x();
262
263 QPen pen;
264 pen.setColor(m_cPenColor);
265 pen.setWidth(2);
266
267 //Clear old and plot new filter path
268 m_pGraphicsItemPath = addPath(path, pen);
269}
270
271//=============================================================================================================
272
Contains the declaration of the FilterPlotScene class.
void updateFilter(const RTPROCESSINGLIB::FilterKernel &operatorFilter, int samplingFreq, int cutOffLow, int cutOffHigh)
QGraphicsPathItem * m_pGraphicsItemPath
RTPROCESSINGLIB::FilterKernel m_pCurrentFilter
FilterPlotScene(QGraphicsView *view, QObject *parent=0)
void plotMagnitudeDiagram(int samplingFreq, const QString &filtername=QString())
The LayoutScene class provides a reimplemented QGraphicsScene for 2D layout plotting....
Definition layoutscene.h:82
QGraphicsView * m_qvView
The FilterKernel class provides methods to create/design a FIR filter kernel.
static QVector< FilterParameter > m_filterTypes