Option: restrict marker position
This commit is contained in:
parent
ce84370a03
commit
26ba329a0c
@ -110,7 +110,7 @@ VirtualDevice::VirtualDevice(QString serial)
|
||||
zerospan = false;
|
||||
|
||||
// Check if this is a compound device
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
for(auto cd : pref.compoundDevices) {
|
||||
if(cd->name == serial) {
|
||||
// connect request to this compound device
|
||||
@ -257,8 +257,8 @@ bool VirtualDevice::setVNA(const VirtualDevice::VNASettings &s, std::function<vo
|
||||
portStageMapping[s.excitedPorts[i]] = i;
|
||||
}
|
||||
|
||||
auto pref = Preferences::getInstance();
|
||||
Protocol::SweepSettings sd;
|
||||
auto& pref = Preferences::getInstance();
|
||||
Protocol::SweepSettings sd = {};
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.points = s.points;
|
||||
@ -335,8 +335,8 @@ bool VirtualDevice::setSA(const VirtualDevice::SASettings &s, std::function<void
|
||||
return false;
|
||||
}
|
||||
zerospan = s.freqStart == s.freqStop;
|
||||
auto pref = Preferences::getInstance();
|
||||
Protocol::SpectrumAnalyzerSettings sd;
|
||||
auto& pref = Preferences::getInstance();
|
||||
Protocol::SpectrumAnalyzerSettings sd = {};
|
||||
sd.f_start = s.freqStart;
|
||||
sd.f_stop = s.freqStop;
|
||||
sd.pointNum = s.points;
|
||||
@ -410,8 +410,8 @@ bool VirtualDevice::setSG(const SGSettings &s)
|
||||
if(!info.supportsSGmode) {
|
||||
return false;
|
||||
}
|
||||
auto pref = Preferences::getInstance();
|
||||
Protocol::PacketInfo packet;
|
||||
auto& pref = Preferences::getInstance();
|
||||
Protocol::PacketInfo packet = {};
|
||||
packet.type = Protocol::PacketType::Generator;
|
||||
Protocol::GeneratorSettings &sd = packet.generator;
|
||||
sd.frequency = s.freq;
|
||||
@ -485,7 +485,7 @@ bool VirtualDevice::setExtRef(QString option_in, QString option_out)
|
||||
refOut = Reference::OutFreq::Off;
|
||||
}
|
||||
|
||||
Protocol::PacketInfo p;
|
||||
Protocol::PacketInfo p = {};
|
||||
p.type = Protocol::PacketType::Reference;
|
||||
switch(refIn) {
|
||||
case Reference::TypeIn::Internal:
|
||||
@ -518,7 +518,7 @@ bool VirtualDevice::setExtRef(QString option_in, QString option_out)
|
||||
|
||||
std::set<QString> VirtualDevice::GetAvailableVirtualDevices()
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
auto ret = Device::GetDevices();
|
||||
// Add compound devices as well
|
||||
for(auto vdev : pref.compoundDevices) {
|
||||
|
@ -7,7 +7,7 @@ Generator::Generator(AppWindow *window, QString name)
|
||||
{
|
||||
central = new SignalgeneratorWidget(window, window);
|
||||
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
// set initial values
|
||||
if(pref.Startup.RememberSweepSettings) {
|
||||
|
@ -264,7 +264,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||
SetTGEnabled(false);
|
||||
|
||||
// Set initial sweep settings
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
if(pref.Acquisition.useMedianAveraging) {
|
||||
average.setMode(Averaging::Mode::Median);
|
||||
@ -1130,7 +1130,7 @@ void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
||||
void SpectrumAnalyzer::LoadSweepSettings()
|
||||
{
|
||||
QSettings s;
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
settings.freqStart = s.value("SAStart", pref.Startup.SA.start).toULongLong();
|
||||
settings.freqStop = s.value("SAStop", pref.Startup.SA.stop).toULongLong();
|
||||
ConstrainAndUpdateFrequencies();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <QActionGroup>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QCheckBox>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -24,6 +25,9 @@ Marker::Marker(MarkerModel *model, int number, Marker *parent, QString descr)
|
||||
model(model),
|
||||
parentTrace(nullptr),
|
||||
position(1000000000),
|
||||
minPosition(0),
|
||||
maxPosition(0),
|
||||
restrictPosition(false),
|
||||
number(number),
|
||||
visible(true),
|
||||
data(0),
|
||||
@ -87,7 +91,7 @@ void Marker::assignTrace(Trace *t)
|
||||
if(firstAssignment) {
|
||||
// Marker was just created and this is the first assignment to a trace.
|
||||
// Use display format on graph from preferences
|
||||
auto p = Preferences::getInstance();
|
||||
auto& p = Preferences::getInstance();
|
||||
if(p.Marker.defaultBehavior.showDataOnGraphs) {
|
||||
if(p.Marker.defaultBehavior.showAllData) {
|
||||
for(auto f : applicableFormats()) {
|
||||
@ -644,6 +648,22 @@ QString Marker::readableType()
|
||||
}
|
||||
}
|
||||
|
||||
QString Marker::domainToUnit()
|
||||
{
|
||||
return domainToUnit(getDomain());
|
||||
}
|
||||
|
||||
QString Marker::domainToUnit(Trace::DataType domain)
|
||||
{
|
||||
switch(domain) {
|
||||
case Trace::DataType::Frequency: return "Hz";
|
||||
case Trace::DataType::Power: return "dBm";
|
||||
case Trace::DataType::Time: return "s";
|
||||
case Trace::DataType::TimeZeroSpan: return "s";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void Marker::setPosition(double pos)
|
||||
{
|
||||
position = pos;
|
||||
@ -938,6 +958,14 @@ void Marker::constrainPosition()
|
||||
{
|
||||
if(parentTrace) {
|
||||
if(parentTrace->size() > 0) {
|
||||
if(restrictPosition) {
|
||||
if(position > maxPosition) {
|
||||
position = maxPosition;
|
||||
}
|
||||
if(position < minPosition) {
|
||||
position = minPosition;
|
||||
}
|
||||
}
|
||||
if(position > parentTrace->maxX()) {
|
||||
position = parentTrace->maxX();
|
||||
} else if(position < parentTrace->minX()) {
|
||||
@ -1166,6 +1194,9 @@ nlohmann::json Marker::toJSON()
|
||||
j["type"] = typeToString(type).toStdString();
|
||||
j["number"] = number;
|
||||
j["position"] = position;
|
||||
j["minPosition"] = minPosition;
|
||||
j["maxPosition"] = maxPosition;
|
||||
j["restrictPosition"] = restrictPosition;
|
||||
if(group) {
|
||||
j["group"] = group->getNumber();
|
||||
}
|
||||
@ -1205,6 +1236,9 @@ void Marker::fromJSON(nlohmann::json j)
|
||||
creationTimestamp = j.value("creationTimestamp", QDateTime::currentSecsSinceEpoch());
|
||||
number = j.value("number", 1);
|
||||
position = j.value("position", 0.0);
|
||||
minPosition = j.value("minPosition", 0.0);
|
||||
maxPosition = j.value("maxPosition", 0.0);
|
||||
restrictPosition = j.value("restrictPosition", false);
|
||||
visible = j.value("visible", true);
|
||||
|
||||
unsigned int hash = j["trace"];
|
||||
@ -1458,6 +1492,59 @@ SIUnitEdit *Marker::getSettingsEditor()
|
||||
return ret;
|
||||
}
|
||||
|
||||
QWidget *Marker::getRestrictEditor()
|
||||
{
|
||||
auto w = new QWidget;
|
||||
auto layout = new QHBoxLayout;
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
auto cb = new QCheckBox;
|
||||
cb->setChecked(restrictPosition);
|
||||
layout->addWidget(cb);
|
||||
auto min = new SIUnitEdit;
|
||||
min->setPrefixes("pnum kMG");
|
||||
min->setUnit(domainToUnit());
|
||||
min->setPrecision(5);
|
||||
min->setValue(minPosition);
|
||||
min->setEnabled(restrictPosition);
|
||||
layout->addWidget(new QLabel("from"));
|
||||
layout->addWidget(min);
|
||||
auto max = new SIUnitEdit;
|
||||
max->setPrefixes("pnum kMG");
|
||||
max->setUnit(domainToUnit());
|
||||
max->setPrecision(5);
|
||||
max->setValue(maxPosition);
|
||||
max->setEnabled(restrictPosition);
|
||||
layout->addWidget(new QLabel("to"));
|
||||
layout->addWidget(max);
|
||||
|
||||
connect(cb, &QCheckBox::toggled, this, [=](){
|
||||
restrictPosition = cb->isChecked();
|
||||
min->setEnabled(restrictPosition);
|
||||
max->setEnabled(restrictPosition);
|
||||
constrainPosition();
|
||||
update();
|
||||
});
|
||||
connect(min, &SIUnitEdit::valueChanged, this, [=](){
|
||||
minPosition = min->value();
|
||||
if(maxPosition < minPosition) {
|
||||
maxPosition = minPosition;
|
||||
max->setValueQuiet(maxPosition);
|
||||
}
|
||||
constrainPosition();
|
||||
});
|
||||
connect(max, &SIUnitEdit::valueChanged, this, [=](){
|
||||
maxPosition = max->value();
|
||||
if(maxPosition < minPosition) {
|
||||
minPosition = maxPosition;
|
||||
min->setValueQuiet(minPosition);
|
||||
}
|
||||
constrainPosition();
|
||||
});
|
||||
|
||||
w->setLayout(layout);
|
||||
return w;
|
||||
}
|
||||
|
||||
void Marker::adjustSettings(double value)
|
||||
{
|
||||
switch(getDomain()) {
|
||||
@ -1565,20 +1652,22 @@ void Marker::update()
|
||||
// empty trace, nothing to do
|
||||
return;
|
||||
}
|
||||
auto xmin = restrictPosition ? minPosition : numeric_limits<double>::lowest();
|
||||
auto xmax = restrictPosition ? maxPosition : numeric_limits<double>::max();
|
||||
switch(type) {
|
||||
case Type::Manual:
|
||||
case Type::Delta:
|
||||
// nothing to do
|
||||
break;
|
||||
case Type::Maximum:
|
||||
setPosition(parentTrace->findExtremum(true));
|
||||
setPosition(parentTrace->findExtremum(true, xmin, xmax));
|
||||
break;
|
||||
case Type::Minimum:
|
||||
setPosition(parentTrace->findExtremum(false));
|
||||
setPosition(parentTrace->findExtremum(false, xmin, xmax));
|
||||
break;
|
||||
case Type::PeakTable: {
|
||||
deleteHelperMarkers();
|
||||
auto peaks = parentTrace->findPeakFrequencies(100, peakThreshold);
|
||||
auto peaks = parentTrace->findPeakFrequencies(100, peakThreshold, 3.0, xmin, xmax);
|
||||
char suffix = 'a';
|
||||
for(auto p : peaks) {
|
||||
auto helper = new Marker(model, number, this);
|
||||
@ -1600,7 +1689,7 @@ void Marker::update()
|
||||
break;
|
||||
} else {
|
||||
// find the maximum
|
||||
auto peakFreq = parentTrace->findExtremum(true);
|
||||
auto peakFreq = parentTrace->findExtremum(true, xmin, xmax);
|
||||
// this marker shows the insertion loss
|
||||
setPosition(peakFreq);
|
||||
// find the cutoff frequency
|
||||
@ -1609,7 +1698,11 @@ void Marker::update()
|
||||
auto cutoff = peakAmplitude + cutoffAmplitude;
|
||||
int inc = type == Type::Lowpass ? 1 : -1;
|
||||
while(index >= 0 && index < (int) parentTrace->size()) {
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(index).y);
|
||||
auto sample = parentTrace->sample(index);
|
||||
if(sample.x > xmax) {
|
||||
break;
|
||||
}
|
||||
auto amplitude = Util::SparamTodB(sample.y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
@ -1640,7 +1733,11 @@ void Marker::update()
|
||||
|
||||
auto low_index = index;
|
||||
while(low_index >= 0) {
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(low_index).y);
|
||||
auto sample = parentTrace->sample(low_index);
|
||||
if(sample.x < xmin) {
|
||||
break;
|
||||
}
|
||||
auto amplitude = Util::SparamTodB(sample.y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
@ -1654,7 +1751,11 @@ void Marker::update()
|
||||
|
||||
auto high_index = index;
|
||||
while(high_index < (int) parentTrace->size()) {
|
||||
auto amplitude = Util::SparamTodB(parentTrace->sample(high_index).y);
|
||||
auto sample = parentTrace->sample(high_index);
|
||||
if(sample.x > xmax) {
|
||||
break;
|
||||
}
|
||||
auto amplitude = Util::SparamTodB(sample.y);
|
||||
if(amplitude <= cutoff) {
|
||||
break;
|
||||
}
|
||||
@ -1670,7 +1771,7 @@ void Marker::update()
|
||||
}
|
||||
break;
|
||||
case Type::TOI: {
|
||||
auto peaks = parentTrace->findPeakFrequencies(2);
|
||||
auto peaks = parentTrace->findPeakFrequencies(2, -100, 3.0, xmin, xmax);
|
||||
if(peaks.size() != 2) {
|
||||
// error finding peaks, do nothing
|
||||
break;
|
||||
@ -1691,13 +1792,16 @@ void Marker::update()
|
||||
break;
|
||||
case Type::P1dB: {
|
||||
// find maximum
|
||||
auto maxpos = parentTrace->findExtremum(true);
|
||||
auto maxpos = parentTrace->findExtremum(true, xmin, xmax);
|
||||
// starting at the maximum point, traverse trace data towards higher power levels until amplitude dropped by 1dB
|
||||
auto maxindex = parentTrace->index(maxpos);
|
||||
auto maxpower = abs(parentTrace->sample(maxindex).y);
|
||||
double p1db = parentTrace->maxX();
|
||||
double p1db = parentTrace->maxX() > xmax ? xmax : parentTrace->maxX();
|
||||
for(unsigned int i = maxindex; i < parentTrace->size(); i++) {
|
||||
auto sample = parentTrace->sample(i);
|
||||
if(sample.x > xmax) {
|
||||
break;
|
||||
}
|
||||
if(Util::SparamTodB(maxpower) - Util::SparamTodB(sample.y) >= 1.0) {
|
||||
p1db = sample.x;
|
||||
break;
|
||||
|
@ -15,7 +15,7 @@ class MarkerGroup;
|
||||
|
||||
class Marker : public QObject, public Savable
|
||||
{
|
||||
Q_OBJECT;
|
||||
Q_OBJECT
|
||||
public:
|
||||
Marker(MarkerModel *model, int number = 1, Marker *parent = nullptr, QString descr = QString());
|
||||
~Marker();
|
||||
@ -61,6 +61,8 @@ public:
|
||||
QString readableSettings();
|
||||
QString tooltipSettings();
|
||||
QString readableType();
|
||||
QString domainToUnit();
|
||||
static QString domainToUnit(Trace::DataType domain);
|
||||
|
||||
double getPosition() const;
|
||||
std::complex<double> getData() const;
|
||||
@ -96,6 +98,7 @@ public:
|
||||
QWidget *getTypeEditor(QAbstractItemDelegate *delegate = nullptr);
|
||||
void updateTypeFromEditor(QWidget *c);
|
||||
SIUnitEdit* getSettingsEditor();
|
||||
QWidget *getRestrictEditor();
|
||||
void adjustSettings(double value);
|
||||
bool isVisible();
|
||||
void setVisible(bool visible);
|
||||
@ -184,6 +187,9 @@ private:
|
||||
Trace *parentTrace;
|
||||
unsigned long creationTimestamp;
|
||||
double position;
|
||||
double minPosition;
|
||||
double maxPosition;
|
||||
bool restrictPosition;
|
||||
int number;
|
||||
bool visible;
|
||||
// Frequency domain: S parameter
|
||||
|
@ -279,6 +279,7 @@ QVariant MarkerModel::headerData(int section, Qt::Orientation orientation, int r
|
||||
case ColIndexTrace: return "Trace";
|
||||
case ColIndexType: return "Type";
|
||||
case ColIndexSettings: return "Settings";
|
||||
case ColIndexRestrict: return "Restrict";
|
||||
case ColIndexData: return "Data";
|
||||
}
|
||||
break;
|
||||
@ -291,6 +292,7 @@ QVariant MarkerModel::headerData(int section, Qt::Orientation orientation, int r
|
||||
case ColIndexTrace: return "The trace from which the marker gets its data";
|
||||
case ColIndexType: return "Depending on marker type, it can be positioned by the user or will be set automatically";
|
||||
case ColIndexSettings: return "Configurable marker parameter, depends on the marker type";
|
||||
case ColIndexRestrict: return "Restrict the range available for this marker";
|
||||
case ColIndexData: return "Tracedata at the marker position";
|
||||
}
|
||||
break;
|
||||
@ -334,6 +336,7 @@ Qt::ItemFlags MarkerModel::flags(const QModelIndex &index) const
|
||||
case ColIndexTrace: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexType: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexSettings: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexRestrict: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexData: flags |= Qt::ItemIsEnabled; break;
|
||||
}
|
||||
auto marker = markerFromIndex(index);
|
||||
@ -524,3 +527,22 @@ void MarkerTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *, con
|
||||
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
|
||||
marker->updateTypeFromEditor(editor);
|
||||
}
|
||||
|
||||
QSize MarkerRestrictDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return QSize(0, rowHeight);
|
||||
}
|
||||
|
||||
QWidget *MarkerRestrictDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
|
||||
auto editor = marker->getRestrictEditor();
|
||||
editor->setMaximumHeight(rowHeight);
|
||||
editor->setParent(parent);
|
||||
return editor;
|
||||
}
|
||||
|
||||
void MarkerRestrictDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
class MarkerTraceDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT;
|
||||
Q_OBJECT
|
||||
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const override;
|
||||
@ -31,7 +31,7 @@ Q_DECLARE_METATYPE(MarkerWidgetTraceInfo)
|
||||
|
||||
class MarkerTypeDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT;
|
||||
Q_OBJECT
|
||||
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
@ -39,7 +39,15 @@ class MarkerTypeDelegate : public QStyledItemDelegate
|
||||
|
||||
class MarkerSettingsDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT;
|
||||
Q_OBJECT
|
||||
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
};
|
||||
|
||||
class MarkerRestrictDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
@ -59,6 +67,7 @@ public:
|
||||
ColIndexTrace,
|
||||
ColIndexType,
|
||||
ColIndexSettings,
|
||||
ColIndexRestrict,
|
||||
ColIndexData,
|
||||
ColIndexLast,
|
||||
};
|
||||
|
@ -27,6 +27,7 @@ MarkerWidget::MarkerWidget(MarkerModel &model, QWidget *parent) :
|
||||
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexTrace, new MarkerTraceDelegate);
|
||||
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexType, new MarkerTypeDelegate);
|
||||
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexSettings, new MarkerSettingsDelegate);
|
||||
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexRestrict, new MarkerRestrictDelegate);
|
||||
|
||||
ui->treeView->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
|
||||
ui->treeView->installEventFilter(this);
|
||||
@ -36,6 +37,7 @@ MarkerWidget::MarkerWidget(MarkerModel &model, QWidget *parent) :
|
||||
ui->treeView->setColumnWidth(MarkerModel::ColIndexVisible, 20);
|
||||
ui->treeView->setColumnWidth(MarkerModel::ColIndexTrace, 60);
|
||||
ui->treeView->setColumnWidth(MarkerModel::ColIndexType, 120);
|
||||
ui->treeView->setColumnWidth(MarkerModel::ColIndexRestrict, 200);
|
||||
|
||||
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->treeView, &QTreeView::customContextMenuRequested, [&](const QPoint &p){
|
||||
@ -175,7 +177,7 @@ bool MarkerWidget::eventFilter(QObject *, QEvent *event)
|
||||
void MarkerWidget::updatePersistentEditors()
|
||||
{
|
||||
for(int i=0;i<model.rowCount();i++) {
|
||||
auto columns = {MarkerModel::ColIndexTrace, MarkerModel::ColIndexType};
|
||||
auto columns = {MarkerModel::ColIndexTrace, MarkerModel::ColIndexType, MarkerModel::ColIndexRestrict};
|
||||
for(auto c : columns) {
|
||||
auto index = model.index(i, c);
|
||||
ui->treeView->closePersistentEditor(index);
|
||||
|
@ -334,7 +334,7 @@ void Math::TimeGateGraph::paintEvent(QPaintEvent *event)
|
||||
auto input = gate->getInput()->rData();
|
||||
|
||||
Q_UNUSED(event)
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
QPainter p(this);
|
||||
// fill background
|
||||
p.setBackground(QBrush(pref.Graphs.Color.background));
|
||||
|
@ -1206,11 +1206,14 @@ double Trace::maxX()
|
||||
}
|
||||
}
|
||||
|
||||
double Trace::findExtremum(bool max)
|
||||
double Trace::findExtremum(bool max, double xmin, double xmax)
|
||||
{
|
||||
double compare = max ? numeric_limits<double>::min() : numeric_limits<double>::max();
|
||||
double freq = 0.0;
|
||||
for(auto sample : lastMath->rData()) {
|
||||
if(sample.x < xmin || sample.x > xmax) {
|
||||
continue;
|
||||
}
|
||||
double amplitude = abs(sample.y);
|
||||
if((max && (amplitude > compare)) || (!max && (amplitude < compare))) {
|
||||
// higher/lower extremum found
|
||||
@ -1221,7 +1224,7 @@ double Trace::findExtremum(bool max)
|
||||
return freq;
|
||||
}
|
||||
|
||||
std::vector<double> Trace::findPeakFrequencies(unsigned int maxPeaks, double minLevel, double minValley)
|
||||
std::vector<double> Trace::findPeakFrequencies(unsigned int maxPeaks, double minLevel, double minValley, double xmin, double xmax)
|
||||
{
|
||||
if(lastMath->getDataType() != DataType::Frequency) {
|
||||
// not in frequency domain
|
||||
@ -1236,6 +1239,9 @@ std::vector<double> Trace::findPeakFrequencies(unsigned int maxPeaks, double min
|
||||
double max_dbm = -200.0;
|
||||
double min_dbm = 200.0;
|
||||
for(auto d : lastMath->rData()) {
|
||||
if(d.x < xmin || d.x > xmax) {
|
||||
continue;
|
||||
}
|
||||
double dbm = Util::SparamTodB(d.y);
|
||||
if((dbm >= max_dbm) && (min_dbm <= dbm - minValley)) {
|
||||
// potential peak frequency
|
||||
|
@ -67,13 +67,14 @@ public:
|
||||
unsigned int size() const;
|
||||
double minX();
|
||||
double maxX();
|
||||
double findExtremum(bool max);
|
||||
double findExtremum(bool max, double xmin = std::numeric_limits<double>::lowest(), double xmax = std::numeric_limits<double>::max());
|
||||
/* Searches for peaks in the trace data and returns the peak frequencies in ascending order.
|
||||
* Up to maxPeaks will be returned, with higher level peaks taking priority over lower level peaks.
|
||||
* Only peaks with at least minLevel will be considered.
|
||||
* To detect the next peak, the signal first has to drop at least minValley below the peak level.
|
||||
*/
|
||||
std::vector<double> findPeakFrequencies(unsigned int maxPeaks = 100, double minLevel = -100.0, double minValley = 3.0);
|
||||
std::vector<double> findPeakFrequencies(unsigned int maxPeaks = 100, double minLevel = -100.0, double minValley = 3.0,
|
||||
double xmin = std::numeric_limits<double>::lowest(), double xmax = std::numeric_limits<double>::max());
|
||||
enum class SampleType {
|
||||
Frequency,
|
||||
TimeImpulse,
|
||||
|
@ -168,7 +168,7 @@ void TracePlot::paintEvent(QPaintEvent *event)
|
||||
}
|
||||
|
||||
Q_UNUSED(event)
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
QPainter p(this);
|
||||
// p.setRenderHint(QPainter::Antialiasing);
|
||||
// fill background
|
||||
|
@ -80,7 +80,7 @@ void TracePolarChart::axisSetupDialog()
|
||||
}
|
||||
|
||||
void TracePolarChart::draw(QPainter &p) {
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
auto w = p.window();
|
||||
|
@ -189,7 +189,7 @@ bool TraceSmithChart::configureForTrace(Trace *t)
|
||||
}
|
||||
|
||||
void TraceSmithChart::draw(QPainter &p) {
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
// translate coordinate system so that the smith chart sits in the origin and has a size of 1
|
||||
auto w = p.window();
|
||||
|
@ -210,7 +210,7 @@ void TraceWaterfall::updateContextMenu()
|
||||
|
||||
void TraceWaterfall::draw(QPainter &p)
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
int xAxisSpace = pref.Graphs.fontSizeAxis * 3;
|
||||
constexpr int topMargin = 10;
|
||||
|
@ -348,7 +348,7 @@ bool TraceXYPlot::supported(Trace *t)
|
||||
|
||||
void TraceXYPlot::draw(QPainter &p)
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
limitPassing = true;
|
||||
|
||||
|
@ -61,8 +61,8 @@ void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
||||
p.measurements[name] = corrected.m11;
|
||||
}
|
||||
// handle the rest of the measurements
|
||||
for(int i=0;i<VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
|
||||
for(int j=i+1;j<VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;j++) {
|
||||
for(int i=1;i<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
|
||||
for(int j=i+1;j<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;j++) {
|
||||
if(i == port) {
|
||||
auto S = uncorrected.toSparam(i, j);
|
||||
auto corrected = Sparam(m.p * ABCDparam(S, p.Z0), p.Z0);
|
||||
|
@ -80,7 +80,6 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
auto calLoad = calMenu->addAction("Load");
|
||||
saveCal = calMenu->addAction("Save");
|
||||
calMenu->addSeparator();
|
||||
// saveCal->setEnabled(false);
|
||||
|
||||
connect(calLoad, &QAction::triggered, [=](){
|
||||
LoadCalibration("");
|
||||
@ -97,17 +96,15 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
auto calData = calMenu->addAction("Calibration Measurements");
|
||||
connect(calData, &QAction::triggered, [=](){
|
||||
cal.edit();
|
||||
// StartCalibrationDialog();
|
||||
});
|
||||
|
||||
auto calEditKit = calMenu->addAction("Edit Calibration Kit");
|
||||
connect(calEditKit, &QAction::triggered, [=](){
|
||||
cal.getKit().edit();
|
||||
// cal.getCalibrationKit().edit([=](){
|
||||
// if(calValid) {
|
||||
// ApplyCalibration(cal.getType());
|
||||
// }
|
||||
// });
|
||||
cal.getKit().edit([=](){
|
||||
if(cal.getCaltype().type != Calibration::Type::None) {
|
||||
cal.compute(cal.getCaltype());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
auto calElectronic = calMenu->addAction("Electronic Calibration");
|
||||
@ -518,7 +515,7 @@ VNA::VNA(AppWindow *window, QString name)
|
||||
SetupSCPI();
|
||||
|
||||
// Set initial sweep settings
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
|
||||
if(pref.Acquisition.useMedianAveraging) {
|
||||
average.setMode(Averaging::Mode::Median);
|
||||
@ -1408,7 +1405,7 @@ void VNA::SetupSCPI()
|
||||
|
||||
void VNA::ConstrainAndUpdateFrequencies()
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
double maxFreq;
|
||||
if(pref.Acquisition.harmonicMixing) {
|
||||
maxFreq = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreqHarmonic;
|
||||
@ -1435,7 +1432,7 @@ void VNA::ConstrainAndUpdateFrequencies()
|
||||
|
||||
void VNA::LoadSweepSettings()
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
QSettings s;
|
||||
// frequency sweep settings
|
||||
settings.Freq.start = s.value("SweepFreqStart", pref.Startup.DefaultSweep.f_start).toULongLong();
|
||||
|
@ -171,7 +171,7 @@ AppWindow::AppWindow(QWidget *parent)
|
||||
|
||||
SetupSCPI();
|
||||
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
if(pref.Startup.UseSetupFile) {
|
||||
LoadSetup(pref.Startup.SetupFile);
|
||||
}
|
||||
@ -297,7 +297,7 @@ void AppWindow::SetupMenu()
|
||||
|
||||
void AppWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
if(pref.Startup.UseSetupFile && pref.Startup.AutosaveSetupFile) {
|
||||
SaveSetup(pref.Startup.SetupFile);
|
||||
}
|
||||
@ -983,7 +983,7 @@ void AppWindow::UpdateAcquisitionFrequencies()
|
||||
}
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::AcquisitionFrequencySettings;
|
||||
auto pref = Preferences::getInstance();
|
||||
auto& pref = Preferences::getInstance();
|
||||
p.acquisitionFrequencySettings.IF1 = pref.Acquisition.IF1;
|
||||
p.acquisitionFrequencySettings.ADCprescaler = pref.Acquisition.ADCprescaler;
|
||||
p.acquisitionFrequencySettings.DFTphaseInc = pref.Acquisition.DFTPhaseInc;
|
||||
|
@ -5,6 +5,7 @@ using namespace std;
|
||||
Averaging::Averaging()
|
||||
{
|
||||
averages = 1;
|
||||
numMeasurements = 0;
|
||||
mode = Mode::Mean;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ private:
|
||||
void process(unsigned int pointNum, std::vector<std::complex<double> > &data);
|
||||
|
||||
std::vector<std::deque<std::vector<std::complex<double>>>> avg;
|
||||
int maxPoints;
|
||||
unsigned int numMeasurements;
|
||||
unsigned int averages;
|
||||
Mode mode;
|
||||
|
@ -20,6 +20,9 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
qSetMessagePattern("%{time process}: [%{type}] %{message}");
|
||||
|
||||
Device::RegisterTypes();
|
||||
VirtualDevice::RegisterTypes();
|
||||
|
||||
app = new QApplication(argc, argv);
|
||||
QCoreApplication::setOrganizationName("LibreVNA");
|
||||
QCoreApplication::setApplicationName("LibreVNA-GUI");
|
||||
@ -27,9 +30,6 @@ int main(int argc, char *argv[]) {
|
||||
QCoreApplication::setApplicationVersion(window->getAppVersion() + "-" +
|
||||
window->getAppGitHash().left(9));
|
||||
|
||||
Device::RegisterTypes();
|
||||
VirtualDevice::RegisterTypes();
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
signal(SIGINT, tryExitGracefully);
|
||||
#endif
|
||||
|
@ -389,6 +389,13 @@ void PreferencesDialog::updateFromGUI()
|
||||
p->nonTrivialWriting();
|
||||
}
|
||||
|
||||
Preferences::~Preferences()
|
||||
{
|
||||
for(auto cd : compoundDevices) {
|
||||
delete cd;
|
||||
}
|
||||
}
|
||||
|
||||
void Preferences::load()
|
||||
{
|
||||
QSettings settings;
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
static Preferences& getInstance() {
|
||||
return instance;
|
||||
}
|
||||
Preferences(const Preferences&) = delete;
|
||||
~Preferences();
|
||||
void load();
|
||||
void store();
|
||||
void edit();
|
||||
|
Loading…
Reference in New Issue
Block a user