60 , ui(new
Ui::FilterWindowDockWidget)
62 , m_pMainWindow(mainWindow)
72 m_iWindowSize = MODEL_WINDOW_SIZE;
73 m_iFilterTaps = MODEL_NUM_FILTER_TAPS;
93 double nyquistFrequency = samplingFrequency/2;
95 ui->m_doubleSpinBox_highpass->setMaximum(nyquistFrequency);
96 ui->m_doubleSpinBox_lowpass->setMaximum(nyquistFrequency);
102 void FilterWindow::initSpinBoxes()
104 connect(ui->m_doubleSpinBox_lowpass,static_cast<void (QDoubleSpinBox::*)(
double)>(&QDoubleSpinBox::valueChanged),
107 connect(ui->m_doubleSpinBox_highpass,static_cast<void (QDoubleSpinBox::*)(
double)>(&QDoubleSpinBox::valueChanged),
110 connect(ui->m_doubleSpinBox_transitionband,static_cast<void (QDoubleSpinBox::*)(
double)>(&QDoubleSpinBox::valueChanged),
113 connect(ui->m_spinBox_filterTaps,static_cast<void (QSpinBox::*)(
int)>(&QSpinBox::valueChanged),
117 ui->m_doubleSpinBox_lowpass->installEventFilter(
this);
118 ui->m_doubleSpinBox_highpass->installEventFilter(
this);
119 ui->m_doubleSpinBox_transitionband->installEventFilter(
this);
125 void FilterWindow::initButtons()
127 connect(ui->m_pushButton_applyFilter,&QPushButton::released,
130 connect(ui->m_pushButton_undoFiltering,&QPushButton::released,
133 connect(ui->m_pushButton_exportPlot,&QPushButton::released,
136 connect(ui->m_pushButton_exportFilter,&QPushButton::released,
143 void FilterWindow::initComboBoxes()
145 connect(ui->m_comboBox_designMethod,static_cast<void (QComboBox::*)(
int)>(&QComboBox::currentIndexChanged),
148 connect(ui->m_comboBox_filterType,static_cast<void (QComboBox::*)(
int)>(&QComboBox::currentIndexChanged),
152 ui->m_doubleSpinBox_lowpass->setVisible(
true);
153 ui->m_label_lowpass->setVisible(
true);
154 ui->m_label_lowpass->setText(
"Cut-Off (Hz):");
156 ui->m_doubleSpinBox_highpass->setVisible(
false);
157 ui->m_label_highpass->setVisible(
false);
158 ui->m_doubleSpinBox_highpass->setEnabled(
false);
160 ui->m_spinBox_filterTaps->setVisible(
false);
161 ui->m_label_filterTaps->setVisible(
false);
164 connect(ui->m_comboBox_filterApplyTo, &QComboBox::currentTextChanged,
165 ui->m_comboBox_filterUndoTo, &QComboBox::setCurrentText);
171 void FilterWindow::initFilterPlot()
173 ui->m_graphicsView_filterPlot->setScene(m_pFilterPlotScene);
179 void FilterWindow::initTableViews()
181 ui->m_tableView_activeFilters->setModel(m_pMainWindow->m_pChInfoWindow->
getDataModel());
184 ui->m_tableView_activeFilters->hideColumn(0);
185 ui->m_tableView_activeFilters->hideColumn(2);
186 ui->m_tableView_activeFilters->hideColumn(3);
187 ui->m_tableView_activeFilters->hideColumn(4);
188 ui->m_tableView_activeFilters->hideColumn(5);
189 ui->m_tableView_activeFilters->hideColumn(6);
190 ui->m_tableView_activeFilters->hideColumn(7);
191 ui->m_tableView_activeFilters->hideColumn(8);
193 ui->m_tableView_activeFilters->verticalHeader()->hide();
195 ui->m_tableView_activeFilters->resizeColumnsToContents();
196 ui->m_groupBox_activeFilters->adjustSize();
197 ui->m_groupBox_activeFilters->adjustSize();
203 void FilterWindow::updateFilterPlot()
206 QMutableMapIterator<QString,QSharedPointer<MNEOperator> > it(m_pMainWindow->m_pDataWindow->
getDataModel()->
m_Operators);
207 while(it.hasNext()) {
209 if(it.key() ==
"User defined (See 'Adjust/Filter')") {
212 ui->m_doubleSpinBox_lowpass->value(),
213 ui->m_doubleSpinBox_highpass->value());
217 ui->m_graphicsView_filterPlot->fitInView(m_pFilterPlotScene->itemsBoundingRect(), Qt::KeepAspectRatio);
223 void FilterWindow::resizeEvent(QResizeEvent* event)
226 ui->m_graphicsView_filterPlot->fitInView(m_pFilterPlotScene->itemsBoundingRect(), Qt::KeepAspectRatio);
232 void FilterWindow::keyPressEvent(QKeyEvent * event)
234 if(event->key() == Qt::Key_Enter ||
event->key() == Qt::Key_Return)
237 if((event->modifiers() == Qt::ControlModifier &&
event->key() == Qt::Key_Z) || event->key() == Qt::Key_Delete)
244 bool FilterWindow::eventFilter(QObject *obj, QEvent *event)
246 if(obj == ui->m_doubleSpinBox_highpass || obj == ui->m_doubleSpinBox_lowpass || obj == ui->m_doubleSpinBox_transitionband) {
247 if (event->type() == QEvent::KeyPress) {
248 QKeyEvent *keyEvent =
static_cast<QKeyEvent *
>(event);
250 if((keyEvent->modifiers() == Qt::ControlModifier && keyEvent->key() == Qt::Key_Z))
253 return QObject::eventFilter(obj, event);
258 return QObject::eventFilter(obj, event);
270 Q_UNUSED(currentIndex);
273 switch(ui->m_comboBox_designMethod->currentIndex()) {
275 ui->m_spinBox_filterTaps->setVisible(
false);
276 ui->m_label_filterTaps->setVisible(
false);
280 ui->m_spinBox_filterTaps->setVisible(
true);
281 ui->m_label_filterTaps->setVisible(
true);
286 switch(ui->m_comboBox_filterType->currentIndex()) {
288 ui->m_doubleSpinBox_lowpass->setVisible(
true);
289 ui->m_label_lowpass->setVisible(
true);
290 ui->m_label_lowpass->setText(
"Cut-Off (Hz):");
292 ui->m_doubleSpinBox_highpass->setVisible(
false);
293 ui->m_label_highpass->setVisible(
false);
294 ui->m_doubleSpinBox_highpass->setEnabled(
false);
298 ui->m_doubleSpinBox_highpass->setVisible(
true);
299 ui->m_label_highpass->setVisible(
true);
300 ui->m_label_highpass->setText(
"Cut-Off (Hz):");
302 ui->m_doubleSpinBox_lowpass->setVisible(
false);
303 ui->m_label_lowpass->setVisible(
false);
304 ui->m_doubleSpinBox_highpass->setEnabled(
true);
308 ui->m_doubleSpinBox_highpass->setVisible(
true);
309 ui->m_label_highpass->setVisible(
true);
310 ui->m_doubleSpinBox_lowpass->setVisible(
true);
311 ui->m_label_lowpass->setText(
"Cut-Off Low (Hz):");
313 ui->m_label_lowpass->setVisible(
true);
314 ui->m_doubleSpinBox_lowpass->setEnabled(
true);
315 ui->m_doubleSpinBox_highpass->setEnabled(
true);
316 ui->m_label_highpass->setText(
"Cut-Off High (Hz):");
329 double lowpassHz = ui->m_doubleSpinBox_lowpass->value();
330 double highpassHz = ui->m_doubleSpinBox_highpass->value();
332 double trans_width = ui->m_doubleSpinBox_transitionband->value();
334 double bw = highpassHz-lowpassHz;
335 double center = lowpassHz+bw/2;
338 double nyquistFrequency = samplingFrequency/2;
341 int filterTaps = ui->m_spinBox_filterTaps->value();
342 int fftLength = m_iWindowSize;
343 int exp = ceil(MNEMath::log2(fftLength));
344 fftLength = pow(2, exp+1);
347 if(ui->m_comboBox_filterType->currentText() ==
"Bandpass") {
348 ui->m_doubleSpinBox_highpass->setMinimum(ui->m_doubleSpinBox_lowpass->value());
349 ui->m_doubleSpinBox_lowpass->setMaximum(ui->m_doubleSpinBox_highpass->value());
352 ui->m_doubleSpinBox_highpass->setMaximum(nyquistFrequency);
353 ui->m_doubleSpinBox_lowpass->setMaximum(nyquistFrequency);
357 ui->m_label_fftLength->setText(QString().number(fftLength));
360 FilterOperator::DesignMethod dMethod;
361 if(ui->m_comboBox_designMethod->currentText() ==
"Tschebyscheff")
362 dMethod = FilterOperator::Tschebyscheff;
364 if(ui->m_comboBox_designMethod->currentText() ==
"Cosine")
365 dMethod = FilterOperator::Cosine;
368 QSharedPointer<MNEOperator> userDefinedFilterOperator;
370 if(ui->m_comboBox_filterType->currentText() ==
"Lowpass") {
371 userDefinedFilterOperator = QSharedPointer<MNEOperator>(
372 new FilterOperator(
"User defined (See 'Adjust/Filter')",FilterOperator::LPF,filterTaps,lowpassHz/nyquistFrequency,0.2,(
double)trans_width/nyquistFrequency,samplingFrequency,fftLength,dMethod));
375 if(ui->m_comboBox_filterType->currentText() ==
"Highpass") {
376 userDefinedFilterOperator = QSharedPointer<MNEOperator>(
377 new FilterOperator(
"User defined (See 'Adjust/Filter')",FilterOperator::HPF,filterTaps,highpassHz/nyquistFrequency,0.2,(
double)trans_width/nyquistFrequency,samplingFrequency,fftLength,dMethod));
380 if(ui->m_comboBox_filterType->currentText() ==
"Bandpass") {
381 userDefinedFilterOperator = QSharedPointer<MNEOperator>(
382 new FilterOperator(
"User defined (See 'Adjust/Filter')",FilterOperator::BPF,filterTaps,(
double)center/nyquistFrequency,(
double)bw/nyquistFrequency,(
double)trans_width/nyquistFrequency,samplingFrequency,fftLength,dMethod));
386 QMutableMapIterator<QString,QSharedPointer<MNEOperator> > it(m_pMainWindow->m_pDataWindow->
getDataModel()->
m_Operators);
387 while(it.hasNext()) {
389 if(it.key() ==
"User defined (See 'Adjust/Filter')") {
390 it.setValue(userDefinedFilterOperator);
406 QMutableMapIterator<QString,QSharedPointer<MNEOperator> > it(m_pMainWindow->m_pDataWindow->
getDataModel()->
m_Operators);
408 while(it.hasNext()) {
410 if(it.key() ==
"User defined (See 'Adjust/Filter')") {
411 m_pMainWindow->m_pDataWindow->
getDataModel()->
applyOperator(QModelIndexList(), it.value(), ui->m_comboBox_filterApplyTo->currentText());
435 QString fileName = QFileDialog::getSaveFileName(
this,
437 QString(
"%1/%2_%3_%4_FilterPlot").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
438 tr(
"Vector graphic(*.svg);;Images (*.png)"));
440 if(!fileName.isEmpty())
443 if(fileName.contains(
".svg"))
445 QSvgGenerator svgGen;
447 svgGen.setFileName(fileName);
448 QRectF rect = m_pFilterPlotScene->itemsBoundingRect();
449 svgGen.setSize(QSize(rect.width(), rect.height()));
452 QPainter painter(&svgGen);
453 m_pFilterPlotScene->render(&painter);
456 if(fileName.contains(
".png"))
458 m_pFilterPlotScene->setSceneRect(m_pFilterPlotScene->itemsBoundingRect());
459 QImage image(m_pFilterPlotScene->sceneRect().size().toSize(), QImage::Format_ARGB32);
460 image.fill(Qt::transparent);
462 QPainter painter(&image);
463 m_pFilterPlotScene->render(&painter);
464 image.save(fileName);
476 QString fileName = QFileDialog::getSaveFileName(
this,
477 "Save filter coefficients",
478 QString(
"%1/%2_%3_%4_FilterCoeffs").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
479 tr(
"Text file(*.txt)"));
481 if(!fileName.isEmpty())
483 QFile file(fileName);
484 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
488 QSharedPointer<FilterOperator> currentFilter;
490 QMutableMapIterator<QString,QSharedPointer<MNEOperator> > it(m_pMainWindow->m_pDataWindow->
getDataModel()->
m_Operators);
491 while(it.hasNext()) {
493 if(it.key() ==
"User defined (See 'Adjust/Filter')") {
494 if(it.value()->m_OperatorType == MNEOperator::FILTER) {
498 QTextStream out(&file);
499 for(
int i = 0 ; i<currentFilter->m_dCoeffA.cols() ;i++)
500 out << currentFilter->m_dCoeffA(i) <<
"\n";
ChInfoModel * getDataModel()
RawModel * getDataModel()
void undoFilter(QModelIndexList chlist, const QSharedPointer< MNEOperator > &filterPtr)
void applyOperator(QModelIndexList chlist, const QSharedPointer< MNEOperator > &operatorPtr, const QString &chType)
QMap< QString, QSharedPointer< MNEOperator > > m_Operators
void filterParametersChanged()
FilterWindow(MainWindow *mainWindow, QWidget *parent=0)
void changeStateSpinBoxes(int currentIndex)
void exportFilterCoefficients()
The FilterPlotScene class provides the scene where a filter respone can be plotted.
Contains the declaration of the FilterWindow class.
void updateFilter(QSharedPointer< MNEOperator > operatorFilter, int samplingFreq, int cutOffLow, int cutOffHigh)
void updateDataTableViews()