diff --git a/vna_qt/mainwindow.C b/vna_qt/mainwindow.C index 98329ca..3028e81 100644 --- a/vna_qt/mainwindow.C +++ b/vna_qt/mainwindow.C @@ -383,8 +383,7 @@ void MainWindow::updatePortExtension() { ui->t_ext1->setText(qs(ssprintf(32, "%.0f ps", round(portExt1Seconds*1e12)))); ui->t_ext2->setText(qs(ssprintf(32, "%.0f ps", round(portExt2Seconds*1e12)))); ui->t_extz->setText(qs(ssprintf(32, "%.2f", portExtZ0))); - for(int i=0;inPoints;i++) - updateViews(i); + updateViews(-1); } static string calFileVer = "calFileVersion 1"; @@ -748,6 +747,22 @@ complex calculatePortExt(complex refl, complex Tcable, d } void MainWindow::updateViews(int freqIndex) { + computeViews(freqIndex); + if(ui->actionDisable_chart_update->isChecked()) return; + nv.updateViews(freqIndex); + + time_t t = time(nullptr); + if(abs(int64_t(t) - int64_t(lastDTFUpdate)) >= 1) + dtf.updateValues(nv.values); + lastDTFUpdate = t; +} + +void MainWindow::computeViews(int freqIndex) { + if(freqIndex < 0) { + for(int i=0; inPoints; i++) + computeViews(i); + return; + } if(freqIndex >= (int)nv.values.size()) return; if(curCal) nv.values.at(freqIndex) = curCal->computeValue(curCalCoeffs.at(freqIndex), this->rawValues.at(freqIndex)); @@ -766,14 +781,6 @@ void MainWindow::updateViews(int freqIndex) { nv.values.at(freqIndex)(1, 0) *= polar(1., 2*M_PI*freqHz*(portExt1Seconds+portExt2Seconds)); // S12 nv.values.at(freqIndex)(0, 1) *= polar(1., 2*M_PI*freqHz*(portExt1Seconds+portExt2Seconds)); - - if(ui->actionDisable_chart_update->isChecked()) return; - nv.updateViews(freqIndex); - - time_t t = time(nullptr); - if(abs(int64_t(t) - int64_t(lastDTFUpdate)) >= 1) - dtf.updateValues(nv.values); - lastDTFUpdate = t; } void MainWindow::on_actionLoad_triggered() { @@ -1039,8 +1046,8 @@ void MainWindow::on_actionFine_tune_triggered() { dialog.modelsChanged = [&]() { for(int i=0; inPoints; i++) { curCalCoeffs.at(i) = curCal->computeCoefficients(curCalMeasurementsArray.at(i), dialog.newModels.at(i)); - updateViews(i); } + updateViews(-1); }; if(dialog.exec() == QDialog::Accepted) { curCalStdModelsArray = dialog.newModels; diff --git a/vna_qt/mainwindow.H b/vna_qt/mainwindow.H index 37c0a7c..0f4cb47 100644 --- a/vna_qt/mainwindow.H +++ b/vna_qt/mainwindow.H @@ -179,6 +179,9 @@ private slots: // update a single point on all views in this->views void updateViews(int freqIndex); + // compute calibrated values but do not refresh widgets; called by updateViews() + void computeViews(int freqIndex); + // called when the vna background thread encounters an error void handleBackgroundError(QString msg); diff --git a/vna_qt/networkview.C b/vna_qt/networkview.C index b057164..87f27d0 100644 --- a/vna_qt/networkview.C +++ b/vna_qt/networkview.C @@ -191,104 +191,36 @@ void NetworkView::updateViews(int freqIndex) { } void NetworkView::updateView(int viewIndex, int freqIndex) { - double period = 1./xAxisStep; - double grpDelayScale = period/(2*M_PI) * 1e3; + SParamView tmp = this->views.at(viewIndex); + // if we are updating all frequencies, compute and replace entire chart at once if(freqIndex < 0) { - for(int i=0;i<(int)values.size();i++) { - updateView(viewIndex,i); + int sz = (int) values.size(); + if(tmp.src.type != SParamViewSource::TYPE_COMPLEX) { + auto* series = dynamic_cast(tmp.view); + QVector pts(sz); + for(int i=0; ireplace(pts); + } else { + for(int i=0; iviews.at(viewIndex); - VNACalibratedValue val = this->values.at(freqIndex); complex entry = val(tmp.src.row,tmp.src.col); - double z0 = 50; - complex Z = -z0*(entry+1.)/(entry-1.); - complex Y = -(entry-1.)/(z0*(entry+1.)); if(tmp.src.type == SParamViewSource::TYPE_COMPLEX) { + // smith chart view auto* view = dynamic_cast(tmp.view); view->points.at(freqIndex) = entry; } else { + // line chart view auto* series = dynamic_cast(tmp.view); - double y = 0; - switch(tmp.src.type) { - case SParamViewSource::TYPE_MAG: - y = dB(norm(entry)); - break; - case SParamViewSource::TYPE_SWR: - y = swr(norm(entry)); - break; - case SParamViewSource::TYPE_PHASE: - y = arg(entry)*180./M_PI; - break; - case SParamViewSource::TYPE_Z_RE: - y = Z.real(); - break; - case SParamViewSource::TYPE_Z_IM: - y = Z.imag(); - break; - case SParamViewSource::TYPE_Z_MAG: - y = abs(Z); - break; - case SParamViewSource::TYPE_Z_CAP: // capacitance in pF - y = -capacitance_inductance(freqHz, Z.imag()) * 1e12; - break; - case SParamViewSource::TYPE_Z_IND: // inductance in nH - y = capacitance_inductance(freqHz, Z.imag()) * 1e9; - break; - case SParamViewSource::TYPE_Y_RE: - y = Y.real() * 1000; - break; - case SParamViewSource::TYPE_Y_IM: - y = Y.imag() * 1000; - break; - case SParamViewSource::TYPE_Y_MAG: - y = abs(Y) * 1000; - break; - case SParamViewSource::TYPE_Y_CAP: // capacitance in pF - y = -capacitance_inductance_Y(freqHz, Y.imag()) * 1e12; - break; - case SParamViewSource::TYPE_Y_IND: // inductance in nH - y = capacitance_inductance_Y(freqHz, Y.imag()) * 1e9; - break; - case SParamViewSource::TYPE_GRPDELAY: - { - if(freqIndex>0) { - VNACalibratedValue prevVal = this->values.at(freqIndex-1); - complex prevEntry = prevVal(tmp.src.row,tmp.src.col); - y = arg(prevEntry) - arg(entry); - if(y>=M_PI) y-=2*M_PI; - if(y<-M_PI) y+=2*M_PI; - } else y=0; - y *= grpDelayScale; - break; - } - default: assert(false); - } - - // clamp values to avoid enlarging labels - switch(tmp.src.type) { - case SParamViewSource::TYPE_Z_CAP: - case SParamViewSource::TYPE_Z_IND: - case SParamViewSource::TYPE_Y_CAP: - case SParamViewSource::TYPE_Y_IND: - if(y < 0) y = 0; - if(y > 999) y = 999; - break; - case SParamViewSource::TYPE_Z_RE: - case SParamViewSource::TYPE_Z_IM: - case SParamViewSource::TYPE_Z_MAG: - if(y < -999) y = -999; - if(y > 999) y = 999; - break; - default: break; - } - - series->replace(freqIndex,series->at(freqIndex).x(), y); + QPointF pt = _computeChartPoint(viewIndex, freqIndex); + series->replace(freqIndex,pt); } } @@ -434,3 +366,90 @@ int NetworkView::addMarker(bool removable) { return newId; } +QPointF NetworkView::_computeChartPoint(int viewIndex, int freqIndex) { + double period = 1./xAxisStep; + double grpDelayScale = period/(2*M_PI) * 1e3; + SParamView tmp = this->views.at(viewIndex); + + VNACalibratedValue val = this->values.at(freqIndex); + complex entry = val(tmp.src.row,tmp.src.col); + double z0 = 50; + complex Z = -z0*(entry+1.)/(entry-1.); + complex Y = -(entry-1.)/(z0*(entry+1.)); + double y = 0; + double freqHz = xAxisAt(freqIndex)*1e6; // only meaningful in frequency domain + switch(tmp.src.type) { + case SParamViewSource::TYPE_MAG: + y = dB(norm(entry)); + break; + case SParamViewSource::TYPE_SWR: + y = swr(norm(entry)); + break; + case SParamViewSource::TYPE_PHASE: + y = arg(entry)*180./M_PI; + break; + case SParamViewSource::TYPE_Z_RE: + y = Z.real(); + break; + case SParamViewSource::TYPE_Z_IM: + y = Z.imag(); + break; + case SParamViewSource::TYPE_Z_MAG: + y = abs(Z); + break; + case SParamViewSource::TYPE_Z_CAP: // capacitance in pF + y = -capacitance_inductance(freqHz, Z.imag()) * 1e12; + break; + case SParamViewSource::TYPE_Z_IND: // inductance in nH + y = capacitance_inductance(freqHz, Z.imag()) * 1e9; + break; + case SParamViewSource::TYPE_Y_RE: + y = Y.real() * 1000; + break; + case SParamViewSource::TYPE_Y_IM: + y = Y.imag() * 1000; + break; + case SParamViewSource::TYPE_Y_MAG: + y = abs(Y) * 1000; + break; + case SParamViewSource::TYPE_Y_CAP: // capacitance in pF + y = -capacitance_inductance_Y(freqHz, Y.imag()) * 1e12; + break; + case SParamViewSource::TYPE_Y_IND: // inductance in nH + y = capacitance_inductance_Y(freqHz, Y.imag()) * 1e9; + break; + case SParamViewSource::TYPE_GRPDELAY: + { + if(freqIndex>0) { + VNACalibratedValue prevVal = this->values.at(freqIndex-1); + complex prevEntry = prevVal(tmp.src.row,tmp.src.col); + y = arg(prevEntry) - arg(entry); + if(y>=M_PI) y-=2*M_PI; + if(y<-M_PI) y+=2*M_PI; + } else y=0; + y *= grpDelayScale; + break; + } + default: assert(false); + } + + // clamp values to avoid enlarging labels + switch(tmp.src.type) { + case SParamViewSource::TYPE_Z_CAP: + case SParamViewSource::TYPE_Z_IND: + case SParamViewSource::TYPE_Y_CAP: + case SParamViewSource::TYPE_Y_IND: + if(y < 0) y = 0; + if(y > 999) y = 999; + break; + case SParamViewSource::TYPE_Z_RE: + case SParamViewSource::TYPE_Z_IM: + case SParamViewSource::TYPE_Z_MAG: + if(y < -999) y = -999; + if(y > 999) y = 999; + break; + default: break; + } + return QPointF(xAxisAt(freqIndex), y); +} + diff --git a/vna_qt/networkview.H b/vna_qt/networkview.H index 607b0f8..3524fc6 100644 --- a/vna_qt/networkview.H +++ b/vna_qt/networkview.H @@ -117,6 +117,8 @@ public: void updateBottomLabels(int marker=-1); void updateYAxis(int viewIndex=-1); int addMarker(bool removable); + + QPointF _computeChartPoint(int viewIndex, int freqIndex); signals: void markerChanged(int marker, int newIndex); };