22#include "ui_filterdesignview.h"
36#include <QStandardPaths>
37#include <QSvgGenerator>
40#include <QApplication>
64,
m_pUi(std::make_unique<Ui::FilterDesignViewWidget>())
91 if (iMaxNumberFilterTaps % 2 != 0) {
92 iMaxNumberFilterTaps--;
95 m_pUi->m_spinBox_filterTaps->setMaximum(iMaxNumberFilterTaps);
96 m_pUi->m_spinBox_filterTaps->setMinimum(16);
106 return m_pUi->m_spinBox_filterTaps->value();
113 if (dSamplingRate <= 0) {
114 qWarning() <<
"[FilterDesignView::setSamplingRate] Sampling frequency is <= 0. Returning.";
120 double nyquistFrequency =
m_dSFreq / 2;
122 m_pUi->m_doubleSpinBox_to->setMaximum(nyquistFrequency);
123 m_pUi->m_doubleSpinBox_from->setMaximum(nyquistFrequency);
142 m_pUi->m_doubleSpinBox_from->setValue(dFrom);
150 m_pUi->m_doubleSpinBox_to->setValue(dTo);
165 return m_pUi->m_comboBox_filterApplyTo->currentText();
172 m_pUi->m_comboBox_filterApplyTo->setCurrentText(sType);
184 QSettings settings(
"MNECPP");
192 settings.setValue(
m_sSettingsPath + QString(
"/FilterDesignView/Position"), this->pos());
203 QSettings settings(
"MNECPP");
206 m_pUi->m_doubleSpinBox_to->setValue(settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/filterTo"), 40.0).toDouble());
207 m_pUi->m_doubleSpinBox_from->setValue(settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/filterFrom"), 1.0).toDouble());
208 m_pUi->m_spinBox_filterTaps->setValue(settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/filterOrder"), 128).toInt());
210 m_pUi->m_doubleSpinBox_transitionband->setValue(settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/filterTransition"), 0.1).toDouble());
211 m_pUi->m_comboBox_filterApplyTo->setCurrentText(settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/filterChannelType"),
"All").toString());
213 QPoint pos = settings.value(
m_sSettingsPath + QString(
"/FilterDesignView/Position"), QPoint(100, 100)).toPoint();
215 QRect screenRect = QApplication::primaryScreen()->geometry();
216 if (!screenRect.contains(pos) && QGuiApplication::screens().size() == 1) {
217 move(QPoint(100, 100));
251 connect(
m_pUi->m_doubleSpinBox_from, &QDoubleSpinBox::editingFinished,
254 connect(
m_pUi->m_doubleSpinBox_to, &QDoubleSpinBox::editingFinished,
257 connect(
m_pUi->m_doubleSpinBox_transitionband, &QDoubleSpinBox::editingFinished,
260 connect(
m_pUi->m_spinBox_filterTaps, &QSpinBox::editingFinished,
264 m_pUi->m_doubleSpinBox_from->installEventFilter(
this);
265 m_pUi->m_doubleSpinBox_to->installEventFilter(
this);
266 m_pUi->m_doubleSpinBox_transitionband->installEventFilter(
this);
273 connect(
m_pUi->m_pushButton_exportPlot, &QPushButton::released,
276 connect(
m_pUi->m_pushButton_exportFilter, &QPushButton::released,
279 connect(
m_pUi->m_pushButton_loadFilter, &QPushButton::released,
288 m_pUi->m_comboBox_designMethod->addItem(filterMethod.getName());
291 connect(
m_pUi->m_comboBox_designMethod,
static_cast<void (QComboBox::*)(
int)
>(&QComboBox::currentIndexChanged),
295 m_pUi->m_doubleSpinBox_from->setVisible(
true);
296 m_pUi->m_label_lowpass->setVisible(
true);
298 m_pUi->m_doubleSpinBox_to->setVisible(
true);
299 m_pUi->m_label_highpass->setVisible(
true);
301 m_pUi->m_spinBox_filterTaps->setVisible(
true);
302 m_pUi->m_label_filterTaps->setVisible(
true);
304 connect(
m_pUi->m_comboBox_filterApplyTo, &QComboBox::currentTextChanged,
315 m_pUi->m_graphicsView_filterPlot->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
316 m_pUi->m_graphicsView_filterPlot->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
333 if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
337 if ((event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z) || event->key() == Qt::Key_Delete) {
349 m_pUi->m_doubleSpinBox_from->value(),
350 m_pUi->m_doubleSpinBox_to->value());
359 Q_UNUSED(currentIndex);
362 switch (
m_pUi->m_comboBox_designMethod->currentIndex()) {
364 m_pUi->m_spinBox_filterTaps->setVisible(
true);
365 m_pUi->m_label_filterTaps->setVisible(
true);
369 m_pUi->m_spinBox_filterTaps->setVisible(
true);
370 m_pUi->m_label_filterTaps->setVisible(
true);
385 double from =
m_pUi->m_doubleSpinBox_from->value();
386 double to =
m_pUi->m_doubleSpinBox_to->value();
388 double trans_width =
m_pUi->m_doubleSpinBox_transitionband->value();
390 double bw = to - from;
391 double center = from + bw / 2;
393 double nyquistFrequency =
m_dSFreq / 2;
397 if (
m_pUi->m_spinBox_filterTaps->value() % 2 != 0) {
402 m_pUi->m_doubleSpinBox_to->setMaximum(nyquistFrequency);
403 m_pUi->m_doubleSpinBox_from->setMaximum(nyquistFrequency);
404 m_pUi->m_doubleSpinBox_to->setMinimum(0);
405 m_pUi->m_doubleSpinBox_from->setMinimum(0);
407 if ((
m_pUi->m_doubleSpinBox_to->value() <
m_pUi->m_doubleSpinBox_from->value())) {
408 m_pUi->m_doubleSpinBox_to->setValue(
m_pUi->m_doubleSpinBox_from->value() + 1);
411 m_pUi->m_doubleSpinBox_to->setMinimum(
m_pUi->m_doubleSpinBox_from->value());
412 m_pUi->m_doubleSpinBox_from->setMaximum(
m_pUi->m_doubleSpinBox_to->value());
420 center / nyquistFrequency,
421 bw / nyquistFrequency,
422 trans_width / nyquistFrequency,
447 QString fileName = QFileDialog::getSaveFileName(
this,
449 QString(
"%1/%2_%3_%4_FilterPlot").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(date.currentDate().year()).arg(date.currentDate().month()).arg(date.currentDate().day()),
450 tr(
"Vector graphic(*.svg);;Images (*.png)"));
452 if (!fileName.isEmpty()) {
454 if (fileName.contains(
".svg")) {
455 QSvgGenerator svgGen;
457 svgGen.setFileName(fileName);
459 svgGen.setSize(QSize(rect.width(), rect.height()));
462 QPainter painter(&svgGen);
466 if (fileName.contains(
".png")) {
469 image.fill(Qt::transparent);
471 QPainter painter(&image);
473 image.save(fileName);
489 filterWriteTemp.
setName(filtername);
491 QString fileName = QFileDialog::getSaveFileName(
this,
492 "Save filter coefficients",
493 QString(
"%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).arg(filtername),
494 tr(
"Text file(*.txt)"));
503 QString path = QFileDialog::getOpenFileName(
this,
504 QString(
"Load filter"),
506 tr(
"txt files (*.txt)"));
508 if (!path.isEmpty()) {
522 qDebug() <<
"Could not load filter.";
536 return m_pUi->m_doubleSpinBox_from->value();
543 return m_pUi->m_doubleSpinBox_to->value();
Full FIFF measurement metadata: everything from FIFFB_MEAS / FIFFB_MEAS_INFO needed to interpret a re...
QGraphicsScene that draws the magnitude (and optional phase) response of a designed FIR / IIR filter.
Interactive FIR / IIR filter design GUI with a live magnitude / phase preview.
Plain-text serialisation of UTILSLIB::FilterKernel coefficient sets.
FIFF file I/O, in-memory data structures and high-level readers/writers.
2-D display widgets and visualisation helpers (charts, topography, colour maps).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
AbstractView(QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
void setMaxAllowedFilterTaps(int iMaxNumberFilterTaps)
void changeStateSpinBoxes(int currentIndex)
void updateFilterFrom(double dFrom)
void setFrom(double dFrom)
void updateGuiMode(GuiMode mode)
void setSamplingRate(double dSamplingRate)
void updateFilterTo(double dTo)
void filterParametersChanged()
std::unique_ptr< Ui::FilterDesignViewWidget > m_pUi
QPointer< FilterPlotScene > m_pFilterPlotScene
void onBtnExportFilterCoefficients()
void resizeEvent(QResizeEvent *event)
virtual void keyPressEvent(QKeyEvent *event)
void onBtnExportFilterPlot()
UTILSLIB::FilterKernel m_filterKernel
void guiStyleChanged(DISPLIB::AbstractView::StyleMode style)
UTILSLIB::FilterKernel getCurrentFilter()
void setChannelType(const QString &sType)
void updateProcessingMode(ProcessingMode mode)
void onSpinBoxFilterChannelType(const QString &channelType)
void filterChannelTypeChanged(const QString &channelType)
void updateGuiFromFilter(const UTILSLIB::FilterKernel &filter)
FilterDesignView(const QString &sSettingsPath, QWidget *parent=0, Qt::WindowFlags f=Qt::Widget)
void filterChanged(const UTILSLIB::FilterKernel &activeFilter)
QGraphicsScene rendering the magnitude (and optional phase) response of a designed FIR / IIR filter.
static bool readFilter(QString path, FilterKernel &filter)
static bool writeFilter(const QString &path, const FilterKernel &filter)
Named filter-design parameter descriptor holding a human-readable name and description (e....
The FilterKernel class provides methods to create/design a FIR filter kernel.
double getParksWidth() const
double getSamplingFrequency() const
static QVector< FilterParameter > m_designMethods
static QVector< FilterParameter > m_filterTypes
void setName(const QString &sFilterName)
int getFilterOrder() const
double getLowpassFreq() const
double getHighpassFreq() const
FilterParameter getDesignMethod() const