mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 09:18:54 -05:00
370 lines
13 KiB
C++
370 lines
13 KiB
C++
///////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) 2022 Jon Beniston, M7RCE <jon@beniston.com> //
|
|
// Copyright (C) 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
|
// //
|
|
// This program is free software; you can redistribute it and/or modify //
|
|
// it under the terms of the GNU General Public License as published by //
|
|
// the Free Software Foundation as version 3 of the License, or //
|
|
// (at your option) any later version. //
|
|
// //
|
|
// This program is distributed in the hope that it will be useful, //
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
// GNU General Public License V3 for more details. //
|
|
// //
|
|
// You should have received a copy of the GNU General Public License //
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <QFileDialog>
|
|
#include <QFile>
|
|
#include <QStandardPaths>
|
|
|
|
#include "util/db.h"
|
|
#include "util/csv.h"
|
|
#include "dsp/spectrummarkers.h"
|
|
#include "gui/dialpopup.h"
|
|
|
|
#include "spectrumcalibrationpointsdialog.h"
|
|
|
|
#include "ui_spectrumcalibrationpointsdialog.h"
|
|
|
|
SpectrumCalibrationPointsDialog::SpectrumCalibrationPointsDialog(
|
|
QList<SpectrumCalibrationPoint>& calibrationPoints,
|
|
SpectrumSettings::CalibrationInterpolationMode& calibrationInterpMode,
|
|
const SpectrumHistogramMarker *markerZero,
|
|
QWidget* parent
|
|
) :
|
|
QDialog(parent),
|
|
ui(new Ui::SpectrumCalibrationPointsDialog),
|
|
m_calibrationPoints(calibrationPoints),
|
|
m_calibrationInterpMode(calibrationInterpMode),
|
|
m_markerZero(markerZero),
|
|
m_calibrationPointIndex(0),
|
|
m_centerFrequency(0),
|
|
m_globalCorrection(0.0),
|
|
m_setElseCorrectGlobal(false)
|
|
{
|
|
ui->setupUi(this);
|
|
ui->calibPointFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
|
ui->calibPointFrequency->setValueRange(false, 10, -9999999999L, 9999999999L);
|
|
ui->calibrationGlobalCorr->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
|
ui->calibrationGlobalCorr->setValueRange(false, 5, -20000L, 4000L, 2);
|
|
ui->relativePower->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
|
ui->relativePower->setValueRange(false, 5, -20000L, 4000L, 2);
|
|
ui->calibratedPower->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
|
|
ui->calibratedPower->setValueRange(false, 5, -20000L, 4000L, 2);
|
|
ui->calibPoint->setMaximum(m_calibrationPoints.size() - 1);
|
|
ui->calibInterpMode->blockSignals(true);
|
|
ui->calibInterpMode->setCurrentIndex((int) m_calibrationInterpMode);
|
|
ui->calibInterpMode->blockSignals(false);
|
|
ui->calibrationGlobalCorr->setValue(m_globalCorrection * 100.0);
|
|
ui->corrOrSet->setText("Cor");
|
|
displayCalibrationPoint();
|
|
DialPopup::addPopupsToChildDials(this);
|
|
}
|
|
|
|
SpectrumCalibrationPointsDialog::~SpectrumCalibrationPointsDialog()
|
|
{}
|
|
|
|
void SpectrumCalibrationPointsDialog::displayCalibrationPoint()
|
|
{
|
|
ui->calibPointFrequency->blockSignals(true);
|
|
ui->calibPoint->blockSignals(true);
|
|
ui->relativePower->blockSignals(true);
|
|
ui->calibratedPower->blockSignals(true);
|
|
|
|
if (m_calibrationPoints.size() == 0)
|
|
{
|
|
ui->calibPoint->setEnabled(false);
|
|
ui->calibPointDel->setEnabled(false);
|
|
ui->relativePower->setEnabled(false);
|
|
ui->calibratedPower->setEnabled(false);
|
|
ui->calibPointFrequency->setEnabled(false);
|
|
ui->importMarkerZero->setEnabled(false);
|
|
ui->centerFrequency->setEnabled(false);
|
|
}
|
|
else
|
|
{
|
|
ui->calibPoint->setEnabled(true);
|
|
ui->calibPointDel->setEnabled(true);
|
|
ui->relativePower->setEnabled(true);
|
|
ui->calibratedPower->setEnabled(true);
|
|
ui->calibPointFrequency->setEnabled(true);
|
|
ui->importMarkerZero->setEnabled(true);
|
|
ui->centerFrequency->setEnabled(true);
|
|
ui->calibPoint->setValue(m_calibrationPointIndex);
|
|
ui->calibPointText->setText(tr("%1").arg(m_calibrationPointIndex));
|
|
double powerDB = CalcDb::dbPower(m_calibrationPoints[m_calibrationPointIndex].m_powerRelativeReference, 1e-20);
|
|
ui->relativePower->setValue(round(powerDB*100.0)); // fixed point 2 decimals
|
|
powerDB = CalcDb::dbPower(m_calibrationPoints[m_calibrationPointIndex].m_powerCalibratedReference, 1e-20);
|
|
ui->calibratedPower->setValue(round(powerDB*100.0)); // fixed point 2 decimals
|
|
ui->calibPointFrequency->setValue(m_calibrationPoints[m_calibrationPointIndex].m_frequency);
|
|
}
|
|
|
|
ui->calibPointFrequency->blockSignals(false);
|
|
ui->calibPoint->blockSignals(false);
|
|
ui->relativePower->blockSignals(false);
|
|
ui->calibratedPower->blockSignals(false);
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPoint_valueChanged(int value)
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPointIndex = value;
|
|
displayCalibrationPoint();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointAdd_clicked()
|
|
{
|
|
m_calibrationPoints.append(SpectrumCalibrationPoint());
|
|
m_calibrationPoints.back().m_frequency = m_centerFrequency;
|
|
m_calibrationPointIndex = m_calibrationPoints.size() - 1;
|
|
ui->calibPoint->setMaximum(m_calibrationPoints.size() - 1);
|
|
ui->calibPoint->setMinimum(0);
|
|
displayCalibrationPoint();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointDel_clicked()
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPoints.removeAt(m_calibrationPointIndex);
|
|
m_calibrationPointIndex = m_calibrationPointIndex < m_calibrationPoints.size() ?
|
|
m_calibrationPointIndex : m_calibrationPointIndex - 1;
|
|
ui->calibPoint->setMaximum(m_calibrationPoints.size() - 1);
|
|
ui->calibPoint->setMinimum(0);
|
|
displayCalibrationPoint();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_relativePower_changed(qint64 value)
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
float powerDB = value / 100.0f;
|
|
m_calibrationPoints[m_calibrationPointIndex].m_powerRelativeReference = CalcDb::powerFromdB(powerDB);
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibratedPower_changed(qint64 value)
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
float powerDB = value / 100.0f;
|
|
m_calibrationPoints[m_calibrationPointIndex].m_powerCalibratedReference = CalcDb::powerFromdB(powerDB);
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointFrequency_changed(qint64 value)
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPoints[m_calibrationPointIndex].m_frequency = value;
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointDuplicate_clicked()
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPoints.push_back(SpectrumCalibrationPoint(m_calibrationPoints[m_calibrationPointIndex]));
|
|
ui->calibPoint->setMaximum(m_calibrationPoints.size() - 1);
|
|
ui->calibPoint->setMinimum(0);
|
|
m_calibrationPointIndex = m_calibrationPoints.size() - 1;
|
|
displayCalibrationPoint();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointsSort_clicked()
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
std::sort(m_calibrationPoints.begin(), m_calibrationPoints.end(), calibrationPointsLessThan);
|
|
m_calibrationPointIndex = 0;
|
|
displayCalibrationPoint();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_importMarkerZero_clicked()
|
|
{
|
|
if ((m_calibrationPoints.size() == 0) || (m_markerZero == nullptr)) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPoints[m_calibrationPointIndex].m_frequency = m_markerZero->m_frequency;
|
|
m_calibrationPoints[m_calibrationPointIndex].m_powerRelativeReference = CalcDb::powerFromdB(m_markerZero->m_powerMax);
|
|
displayCalibrationPoint();
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_centerFrequency_clicked()
|
|
{
|
|
if (m_calibrationPoints.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
m_calibrationPoints[m_calibrationPointIndex].m_frequency = m_centerFrequency;
|
|
displayCalibrationPoint();
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibInterpMode_currentIndexChanged(int index)
|
|
{
|
|
m_calibrationInterpMode = (SpectrumSettings::CalibrationInterpolationMode) index;
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibrationGlobalCorr_changed(qint64 value)
|
|
{
|
|
m_globalCorrection = value / 100.0;
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_corrOrSet_toggled(bool checked)
|
|
{
|
|
if (checked) {
|
|
ui->corrOrSet->setText("Set");
|
|
} else {
|
|
ui->corrOrSet->setText("Cor");
|
|
}
|
|
|
|
m_setElseCorrectGlobal = checked;
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_globalRelativeCorrection_clicked()
|
|
{
|
|
for (auto& calibrationPoint : m_calibrationPoints)
|
|
{
|
|
if (m_setElseCorrectGlobal) {
|
|
calibrationPoint.m_powerRelativeReference = CalcDb::powerFromdB(m_globalCorrection);
|
|
} else {
|
|
calibrationPoint.m_powerRelativeReference *= CalcDb::powerFromdB(m_globalCorrection);
|
|
}
|
|
}
|
|
|
|
displayCalibrationPoint();
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_globalCalibratedCorrection_clicked()
|
|
{
|
|
for (auto& calibrationPoint : m_calibrationPoints)
|
|
{
|
|
if (m_setElseCorrectGlobal) {
|
|
calibrationPoint.m_powerCalibratedReference = CalcDb::powerFromdB(m_globalCorrection);
|
|
} else {
|
|
calibrationPoint.m_powerCalibratedReference *= CalcDb::powerFromdB(m_globalCorrection);
|
|
}
|
|
}
|
|
|
|
displayCalibrationPoint();
|
|
emit updateCalibrationPoints();
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointsExport_clicked()
|
|
{
|
|
QFileDialog fileDialog(
|
|
nullptr,
|
|
"Select file to write calibration points to",
|
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation),
|
|
"*.csv"
|
|
);
|
|
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
|
|
|
if (fileDialog.exec())
|
|
{
|
|
QStringList fileNames = fileDialog.selectedFiles();
|
|
|
|
if (fileNames.size() > 0)
|
|
{
|
|
QFile file(fileNames[0]);
|
|
|
|
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
|
|
{
|
|
QTextStream stream;
|
|
stream.setDevice(&file);
|
|
stream << "Frequency,Relative,Calibrated\n";
|
|
|
|
for (const auto &calibrationPint : m_calibrationPoints)
|
|
{
|
|
|
|
stream << calibrationPint.m_frequency << ","
|
|
<< CalcDb::dbPower(calibrationPint.m_powerRelativeReference, 1e-20) << ","
|
|
<< CalcDb::dbPower(calibrationPint.m_powerCalibratedReference, 1e-20) << "\n";
|
|
}
|
|
|
|
stream.flush();
|
|
file.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SpectrumCalibrationPointsDialog::on_calibPointsImport_clicked()
|
|
{
|
|
QFileDialog fileDialog(
|
|
nullptr,
|
|
"Select .csv calibration points file to read",
|
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation),
|
|
"*.csv"
|
|
);
|
|
|
|
if (fileDialog.exec())
|
|
{
|
|
QStringList fileNames = fileDialog.selectedFiles();
|
|
|
|
if (fileNames.size() > 0)
|
|
{
|
|
QFile file(fileNames[0]);
|
|
|
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
{
|
|
|
|
QTextStream in(&file);
|
|
QString error;
|
|
QHash<QString, int> colIndexes = CSV::readHeader(
|
|
in,
|
|
{"Frequency", "Relative", "Calibrated"},
|
|
error
|
|
);
|
|
|
|
if (error.isEmpty())
|
|
{
|
|
QStringList cols;
|
|
int frequencyCol = colIndexes.value("Frequency");
|
|
int referenceCol = colIndexes.value("Relative");
|
|
int absoluteCol = colIndexes.value("Calibrated");
|
|
|
|
m_calibrationPoints.clear();
|
|
|
|
while (CSV::readRow(in, &cols))
|
|
{
|
|
m_calibrationPoints.push_back(SpectrumCalibrationPoint());
|
|
m_calibrationPoints.back().m_frequency = cols[frequencyCol].toLongLong();
|
|
m_calibrationPoints.back().m_powerRelativeReference = CalcDb::powerFromdB(cols[referenceCol].toFloat());
|
|
m_calibrationPoints.back().m_powerCalibratedReference = CalcDb::powerFromdB(cols[absoluteCol].toFloat());
|
|
}
|
|
|
|
m_calibrationPointIndex = 0;
|
|
ui->calibPoint->setMaximum(m_calibrationPoints.size() - 1);
|
|
ui->calibPoint->setMinimum(0);
|
|
displayCalibrationPoint();
|
|
emit updateCalibrationPoints();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|