diff --git a/Software/PC_Application/Calibration/CalStandardThroughEditDialog.ui b/Software/PC_Application/Calibration/CalStandardThroughEditDialog.ui new file mode 100644 index 0000000..7dfd09c --- /dev/null +++ b/Software/PC_Application/Calibration/CalStandardThroughEditDialog.ui @@ -0,0 +1,190 @@ + + + CalStandardThroughEditDialog + + + + 0 + 0 + 358 + 342 + + + + Edit Through Standard + + + true + + + + + + + + Name: + + + + + + + + + + + + + + Coefficients + + + buttonGroup + + + + + + + Measurement file + + + buttonGroup + + + + + + + + + 0 + + + + + + + Z0: + + + + + + + false + + + + + + + Delay [ps]: + + + + + + + + + + Loss [GΩ/s]: + + + + + + + + + + + + + + + + + + + + + false + + + Update from file + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + SIUnitEdit + QLineEdit +
CustomWidgets/siunitedit.h
+
+ + TouchstoneImport + QWidget +
CustomWidgets/touchstoneimport.h
+ 1 +
+
+ + + + buttonBox + accepted() + CalStandardThroughEditDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CalStandardThroughEditDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + + +
diff --git a/Software/PC_Application/Calibration/calkit.cpp b/Software/PC_Application/Calibration/calkit.cpp index ed1de21..b256fa6 100644 --- a/Software/PC_Application/Calibration/calkit.cpp +++ b/Software/PC_Application/Calibration/calkit.cpp @@ -15,14 +15,6 @@ using json = nlohmann::json; using namespace std; Calkit::Calkit() - : ts_open_m(nullptr), - ts_short_m(nullptr), - ts_load_m(nullptr), - ts_open_f(nullptr), - ts_short_f(nullptr), - ts_load_f(nullptr), - ts_through(nullptr), - ts_cached(false) { // set default values @@ -39,15 +31,11 @@ void Calkit::toFile(QString filename) qDebug() << "Saving calkit to file" << filename; - TransformPathsToRelative(filename); - json j = Savable::createJSON(descr); ofstream file; file.open(filename.toStdString()); file << setw(4) << j << endl; file.close(); - - TransformPathsToAbsolute(filename); } static QString readLine(ifstream &file) { @@ -74,93 +62,87 @@ Calkit Calkit::fromFile(QString filename) throw runtime_error("JSON parsing error: " + string(e.what())); } if(j.contains("SOLT")) { - // older file versions specify Z0 for resistance. Set resistance to Nan to detect missing values later - c.SOLT.load_m.resistance = std::numeric_limits::quiet_NaN(); - c.SOLT.load_f.resistance = std::numeric_limits::quiet_NaN(); +// // older file versions specify Z0 for resistance. Set resistance to Nan to detect missing values later +// c.SOLT.load_m.resistance = std::numeric_limits::quiet_NaN(); +// c.SOLT.load_f.resistance = std::numeric_limits::quiet_NaN(); - qDebug() << "JSON format detected"; - // calkit file uses json format, parse - Savable::parseJSON(j, c.descr); - auto jSOLT = j["SOLT"]; - if (!jSOLT.contains("loadModelCFirst")) { - // older version which did not allow the user to choose the load model. CFirst seems to be the more - // used standard so it is the default for newer calkits. However, old calkits used LFirst so we need - // to keep that to not mess with older calkit files - c.SOLT.loadModelCFirst = false; - } - // adjust Z0/resistance in case of older calkit file version with missing resistance entries - if(isnan(c.SOLT.load_f.resistance)) { - c.SOLT.load_f.resistance = c.SOLT.load_f.Z0; - c.SOLT.load_f.Z0 = 50.0; - } - if(isnan(c.SOLT.load_m.resistance)) { - c.SOLT.load_m.resistance = c.SOLT.load_m.Z0; - c.SOLT.load_m.Z0 = 50.0; - } +// qDebug() << "JSON format detected"; +// // calkit file uses json format, parse +// Savable::parseJSON(j, c.descr); +// auto jSOLT = j["SOLT"]; +// if (!jSOLT.contains("loadModelCFirst")) { +// // older version which did not allow the user to choose the load model. CFirst seems to be the more +// // used standard so it is the default for newer calkits. However, old calkits used LFirst so we need +// // to keep that to not mess with older calkit files +// c.SOLT.loadModelCFirst = false; +// } +// // adjust Z0/resistance in case of older calkit file version with missing resistance entries +// if(isnan(c.SOLT.load_f.resistance)) { +// c.SOLT.load_f.resistance = c.SOLT.load_f.Z0; +// c.SOLT.load_f.Z0 = 50.0; +// } +// if(isnan(c.SOLT.load_m.resistance)) { +// c.SOLT.load_m.resistance = c.SOLT.load_m.Z0; +// c.SOLT.load_m.Z0 = 50.0; +// } } else { - qDebug() << "Legacy format detected"; - // legacy file format, return to beginning of file - file.clear(); - file.seekg(0); - c.SOLT.open_m.useMeasurements = readLine(file).toInt(); - c.SOLT.short_m.useMeasurements = readLine(file).toInt(); - c.SOLT.load_m.useMeasurements = readLine(file).toInt(); - c.SOLT.Through.useMeasurements = readLine(file).toInt(); - c.SOLT.open_m.Z0 = readLine(file).toDouble(); - c.SOLT.open_m.delay = readLine(file).toDouble(); - c.SOLT.open_m.loss = readLine(file).toDouble(); - c.SOLT.open_m.C0 = readLine(file).toDouble(); - c.SOLT.open_m.C1 = readLine(file).toDouble(); - c.SOLT.open_m.C2 = readLine(file).toDouble(); - c.SOLT.open_m.C3 = readLine(file).toDouble(); - c.SOLT.short_m.Z0 = readLine(file).toDouble(); - c.SOLT.short_m.delay = readLine(file).toDouble(); - c.SOLT.short_m.loss = readLine(file).toDouble(); - c.SOLT.short_m.L0 = readLine(file).toDouble(); - c.SOLT.short_m.L1 = readLine(file).toDouble(); - c.SOLT.short_m.L2 = readLine(file).toDouble(); - c.SOLT.short_m.L3 = readLine(file).toDouble(); - c.SOLT.load_m.resistance = readLine(file).toDouble(); - c.SOLT.Through.Z0 = readLine(file).toDouble(); - c.SOLT.Through.delay = readLine(file).toDouble(); - c.SOLT.Through.loss = readLine(file).toDouble(); - if(c.SOLT.open_m.useMeasurements) { - c.SOLT.open_m.file = readLine(file); - c.SOLT.open_m.Sparam = readLine(file).toInt(); - } - if(c.SOLT.short_m.useMeasurements) { - c.SOLT.short_m.file = readLine(file); - c.SOLT.short_m.Sparam = readLine(file).toInt(); - } - if(c.SOLT.load_m.useMeasurements) { - c.SOLT.load_m.file = readLine(file); - c.SOLT.load_m.Sparam = readLine(file).toInt(); - } - if(c.SOLT.Through.useMeasurements) { - c.SOLT.Through.file = readLine(file); - c.SOLT.Through.Sparam1 = readLine(file).toInt(); - c.SOLT.Through.Sparam2 = readLine(file).toInt(); - } - c.TRL.Through.Z0 = readLine(file).toDouble(); - c.TRL.Reflection.isShort = readLine(file).toDouble(); - c.TRL.Line.delay = readLine(file).toDouble(); - c.TRL.Line.minFreq = readLine(file).toDouble(); - c.TRL.Line.maxFreq = readLine(file).toDouble(); +// qDebug() << "Legacy format detected"; +// // legacy file format, return to beginning of file +// file.clear(); +// file.seekg(0); +// c.SOLT.open_m.useMeasurements = readLine(file).toInt(); +// c.SOLT.short_m.useMeasurements = readLine(file).toInt(); +// c.SOLT.load_m.useMeasurements = readLine(file).toInt(); +// c.SOLT.Through.useMeasurements = readLine(file).toInt(); +// c.SOLT.open_m.Z0 = readLine(file).toDouble(); +// c.SOLT.open_m.delay = readLine(file).toDouble(); +// c.SOLT.open_m.loss = readLine(file).toDouble(); +// c.SOLT.open_m.C0 = readLine(file).toDouble(); +// c.SOLT.open_m.C1 = readLine(file).toDouble(); +// c.SOLT.open_m.C2 = readLine(file).toDouble(); +// c.SOLT.open_m.C3 = readLine(file).toDouble(); +// c.SOLT.short_m.Z0 = readLine(file).toDouble(); +// c.SOLT.short_m.delay = readLine(file).toDouble(); +// c.SOLT.short_m.loss = readLine(file).toDouble(); +// c.SOLT.short_m.L0 = readLine(file).toDouble(); +// c.SOLT.short_m.L1 = readLine(file).toDouble(); +// c.SOLT.short_m.L2 = readLine(file).toDouble(); +// c.SOLT.short_m.L3 = readLine(file).toDouble(); +// c.SOLT.load_m.resistance = readLine(file).toDouble(); +// c.SOLT.Through.Z0 = readLine(file).toDouble(); +// c.SOLT.Through.delay = readLine(file).toDouble(); +// c.SOLT.Through.loss = readLine(file).toDouble(); +// if(c.SOLT.open_m.useMeasurements) { +// c.SOLT.open_m.file = readLine(file); +// c.SOLT.open_m.Sparam = readLine(file).toInt(); +// } +// if(c.SOLT.short_m.useMeasurements) { +// c.SOLT.short_m.file = readLine(file); +// c.SOLT.short_m.Sparam = readLine(file).toInt(); +// } +// if(c.SOLT.load_m.useMeasurements) { +// c.SOLT.load_m.file = readLine(file); +// c.SOLT.load_m.Sparam = readLine(file).toInt(); +// } +// if(c.SOLT.Through.useMeasurements) { +// c.SOLT.Through.file = readLine(file); +// c.SOLT.Through.Sparam1 = readLine(file).toInt(); +// c.SOLT.Through.Sparam2 = readLine(file).toInt(); +// } +// c.TRL.Through.Z0 = readLine(file).toDouble(); +// c.TRL.Reflection.isShort = readLine(file).toDouble(); +// c.TRL.Line.delay = readLine(file).toDouble(); +// c.TRL.Line.minFreq = readLine(file).toDouble(); +// c.TRL.Line.maxFreq = readLine(file).toDouble(); - c.SOLT.separate_male_female = false; +// c.SOLT.separate_male_female = false; - InformationBox::ShowMessage("Loading calkit file", "The file \"" + filename + "\" is stored in a deprecated" - " calibration kit format. Future versions of this application might not support" - " it anymore. Please save the calibration kit to update to the new format"); +// InformationBox::ShowMessage("Loading calkit file", "The file \"" + filename + "\" is stored in a deprecated" +// " calibration kit format. Future versions of this application might not support" +// " it anymore. Please save the calibration kit to update to the new format"); } file.close(); - c.TransformPathsToAbsolute(filename); - - // set default values for non-editable items (for now) - c.TRL.Through.Z0 = 50.0; - c.SOLT.Through.Z0 = 50.0; - return c; } @@ -179,305 +161,45 @@ void Calkit::edit(std::function updateCal) bool Calkit::hasSeparateMaleFemaleStandards() { - return SOLT.separate_male_female; + return true; // TODO delete function } class Calkit::SOLT Calkit::toSOLT(double frequency, bool male_standards) { - auto addTransmissionLine = [](complex termination_reflection, double offset_impedance, double offset_delay, double offset_loss, double frequency) -> complex { - // nomenclature and formulas from https://loco.lab.asu.edu/loco-memos/edges_reports/report_20130807.pdf - auto Gamma_T = termination_reflection; - auto f = frequency; - auto w = 2.0 * M_PI * frequency; - auto f_sqrt = sqrt(f / 1e9); - - auto Z_c = complex(offset_impedance + (offset_loss / (2*w)) * f_sqrt, -(offset_loss / (2*w)) * f_sqrt); - auto gamma_l = complex(offset_loss*offset_delay/(2*offset_impedance)*f_sqrt, w*offset_delay+offset_loss*offset_delay/(2*offset_impedance)*f_sqrt); - - auto Z_r = complex(50.0); - - auto Gamma_1 = (Z_c - Z_r) / (Z_c + Z_r); - - auto Gamma_i = (Gamma_1*(1.0-exp(-2.0*gamma_l)-Gamma_1*Gamma_T)+exp(-2.0*gamma_l)*Gamma_T) - / (1.0-Gamma_1*(exp(-2.0*gamma_l)*Gamma_1+Gamma_T*(1.0-exp(-2.0*gamma_l)))); - - return Gamma_i; - }; - - auto Load = male_standards ? SOLT.load_m : SOLT.load_f; - auto Short = male_standards ? SOLT.short_m : SOLT.short_f; - auto Open = male_standards ? SOLT.open_m : SOLT.open_f; - auto ts_load = male_standards ? ts_load_m : ts_load_f; - auto ts_short = male_standards ? ts_short_m : ts_short_f; - auto ts_open = male_standards ? ts_open_m : ts_open_f; - - fillTouchstoneCache(); - class SOLT ref; - if(Load.useMeasurements) { - ref.Load = ts_load->interpolate(frequency).S[0]; - } else { - auto imp_load = complex(Load.resistance, 0); - if (SOLT.loadModelCFirst) { - // C is the first parameter starting from the VNA port. But the load is modeled here starting from - // the other end, so we need to start with the inductor - imp_load += complex(0, frequency * 2 * M_PI * Load.Lseries); - } - // Add parallel capacitor to impedance - if(Load.Cparallel > 0) { - auto imp_C = complex(0, -1.0 / (frequency * 2 * M_PI * Load.Cparallel)); - imp_load = (imp_load * imp_C) / (imp_load + imp_C); - } - if (!SOLT.loadModelCFirst) { - // inductor not added yet, do so now - imp_load += complex(0, frequency * 2 * M_PI * Load.Lseries); - } - ref.Load = (imp_load - complex(50.0)) / (imp_load + complex(50.0)); - ref.Load = addTransmissionLine(ref.Load, Load.Z0, Load.delay*1e-12, 0, frequency); - } - - if(Open.useMeasurements) { - ref.Open = ts_open->interpolate(frequency).S[0]; - } else { - // calculate fringing capacitance for open - double Cfringing = Open.C0 * 1e-15 + Open.C1 * 1e-27 * frequency + Open.C2 * 1e-36 * pow(frequency, 2) + Open.C3 * 1e-45 * pow(frequency, 3); - // convert to impedance - if (Cfringing == 0) { - // special case to avoid issues with infinity - ref.Open = complex(1.0, 0); - } else { - auto imp_open = complex(0, -1.0 / (frequency * 2 * M_PI * Cfringing)); - ref.Open = (imp_open - complex(50.0)) / (imp_open + complex(50.0)); - } - ref.Open = addTransmissionLine(ref.Open, Open.Z0, Open.delay*1e-12, Open.loss*1e9, frequency); - } - - if(Short.useMeasurements) { - ref.Short = ts_short->interpolate(frequency).S[0]; - } else { - // calculate inductance for short - double Lseries = Short.L0 * 1e-12 + Short.L1 * 1e-24 * frequency + Short.L2 * 1e-33 * pow(frequency, 2) + Short.L3 * 1e-42 * pow(frequency, 3); - // convert to impedance - auto imp_short = complex(0, frequency * 2 * M_PI * Lseries); - ref.Short = (imp_short - complex(50.0)) / (imp_short + complex(50.0)); - ref.Short = addTransmissionLine(ref.Short, Short.Z0, Short.delay*1e-12, Short.loss*1e9, frequency); - } - - if(SOLT.Through.useMeasurements) { - auto interp = ts_through->interpolate(frequency); - ref.ThroughS11 = interp.S[0]; - ref.ThroughS12 = interp.S[1]; - ref.ThroughS21 = interp.S[2]; - ref.ThroughS22 = interp.S[3]; - } else { - // calculate effect of through - double through_phaseshift = -2 * M_PI * frequency * SOLT.Through.delay * 1e-12; - double through_att_db = SOLT.Through.loss * 1e9 * 4.3429 * SOLT.Through.delay * 1e-12 / SOLT.Through.Z0 * sqrt(frequency / 1e9);; - double through_att = pow(10.0, -through_att_db / 10.0); - ref.ThroughS12 = polar(through_att, through_phaseshift); - // Assume symmetric and perfectly matched through for other parameters - ref.ThroughS21 = ref.ThroughS12; - ref.ThroughS11 = 0.0; - ref.ThroughS22 = 0.0; - } - - return ref; + return SOLT(); // TODO delete function } class Calkit::TRL Calkit::toTRL(double) { - class TRL trl; - // reflection coefficent sign depends on whether an open or short is used - trl.reflectionIsNegative = TRL.Reflection.isShort; - // assume ideal through for now - trl.ThroughS11 = 0.0; - trl.ThroughS12 = 1.0; - trl.ThroughS21 = 1.0; - trl.ThroughS22 = 0.0; - return trl; + return TRL(); // TODO delete function } double Calkit::minFreqTRL() { - return TRL.Line.minFreq; + return 0; // TODO delete function } double Calkit::maxFreqTRL() { - return TRL.Line.maxFreq; + return std::numeric_limits::max(); // TODO delete function } double Calkit::minFreqSOLT(bool male_standards) { - fillTouchstoneCache(); - double min = 0; - auto ts_load = male_standards ? ts_load_m : ts_load_f; - auto ts_short = male_standards ? ts_short_m : ts_short_f; - auto ts_open = male_standards ? ts_open_m : ts_open_f; - array ts_list = {ts_open, ts_short, ts_load, ts_through}; - // find the highest minimum frequency in all measurement files - for(auto ts : ts_list) { - if(!ts) { - // this calibration standard is defined by coefficients, no minimum frequency - continue; - } - if(ts->minFreq() > min) { - min = ts->minFreq(); - } - } - return min; + return 0; // TODO delete function } double Calkit::maxFreqSOLT(bool male_standards) { - fillTouchstoneCache(); - double max = std::numeric_limits::max(); - auto ts_load = male_standards ? ts_load_m : ts_load_f; - auto ts_short = male_standards ? ts_short_m : ts_short_f; - auto ts_open = male_standards ? ts_open_m : ts_open_f; - array ts_list = {ts_open, ts_short, ts_load, ts_through}; - // find the highest minimum frequency in all measurement files - for(auto ts : ts_list) { - if(!ts) { - // this calibration standard is defined by coefficients, no minimum frequency - continue; - } - if(ts->maxFreq() < max) { - max = ts->maxFreq(); - } - } - return max; + return std::numeric_limits::max(); // TODO delete function } bool Calkit::checkIfValid(double min_freq, double max_freq, bool isTRL, bool include_male, bool include_female) { - auto min_supported = std::numeric_limits::min(); - auto max_supported = std::numeric_limits::max(); - if(isTRL) { - min_supported = TRL.Line.minFreq; - max_supported = TRL.Line.maxFreq; - } else { - if(include_male) { - auto min_male = minFreqSOLT(true); - auto max_male = maxFreqSOLT(true); - if(min_male > min_supported) { - min_supported = min_male; - } - if(max_male > max_supported) { - max_supported = max_male; - } - } - if(include_female) { - auto min_female = minFreqSOLT(false); - auto max_female = maxFreqSOLT(false); - if(min_female > min_supported) { - min_supported = min_female; - } - if(max_female > max_supported) { - max_supported = max_female; - } - } - } - if(min_supported <= min_freq && max_supported >= max_freq) { - return true; - } else { - return false; - } + return true; // TODO delete function } bool Calkit::isTRLReflectionShort() const { - return TRL.Reflection.isShort; -} - -void Calkit::TransformPathsToRelative(QFileInfo d) -{ - vector filenames = {&SOLT.short_m.file, &SOLT.open_m.file, &SOLT.load_m.file, &SOLT.short_f.file, &SOLT.open_f.file, &SOLT.load_f.file, &SOLT.Through.file}; - for(auto f : filenames) { - if(f->isEmpty()) { - continue; - } - if(QFileInfo(*f).isAbsolute()) { - QString buf = *f; - *f = d.dir().relativeFilePath(*f); - qDebug() << "Transformed" << buf << "to" << *f << "(to relative)"; - } - } -} - -void Calkit::TransformPathsToAbsolute(QFileInfo d) -{ - vector filenames = {&SOLT.short_m.file, &SOLT.open_m.file, &SOLT.load_m.file, &SOLT.short_f.file, &SOLT.open_f.file, &SOLT.load_f.file, &SOLT.Through.file}; - for(auto f : filenames) { - if(f->isEmpty()) { - continue; - } - if(QFileInfo(*f).isRelative()) { - auto absDir = QDir(d.dir().path() + "/" + *f); - QString buf = *f; - *f = absDir.absolutePath(); - qDebug() << "Transformed" << buf << "to" << *f << "(to absolute)"; - } - } -} - -void Calkit::clearTouchstoneCache() -{ - delete ts_open_m; - ts_open_m = nullptr; - delete ts_short_m; - ts_short_m = nullptr; - delete ts_load_m; - ts_load_m = nullptr; - delete ts_open_f; - ts_open_f = nullptr; - delete ts_short_f; - ts_short_f = nullptr; - delete ts_load_f; - ts_load_f = nullptr; - delete ts_through; - ts_through = nullptr; - ts_cached = false; -} - -void Calkit::fillTouchstoneCache() -{ - if(ts_cached) { - return; - } - if(SOLT.open_m.useMeasurements) { - ts_open_m = new Touchstone(1); - *ts_open_m = Touchstone::fromFile(SOLT.open_m.file.toStdString()); - ts_open_m->reduceTo1Port(SOLT.open_m.Sparam); - } - if(SOLT.short_m.useMeasurements) { - ts_short_m = new Touchstone(1); - *ts_short_m = Touchstone::fromFile(SOLT.short_m.file.toStdString()); - ts_short_m->reduceTo1Port(SOLT.short_m.Sparam); - } - if(SOLT.load_m.useMeasurements) { - ts_load_m = new Touchstone(1); - *ts_load_m = Touchstone::fromFile(SOLT.load_m.file.toStdString()); - ts_load_m->reduceTo1Port(SOLT.load_m.Sparam); - } - if(SOLT.open_f.useMeasurements) { - ts_open_f = new Touchstone(1); - *ts_open_f = Touchstone::fromFile(SOLT.open_f.file.toStdString()); - ts_open_f->reduceTo1Port(SOLT.open_f.Sparam); - } - if(SOLT.short_f.useMeasurements) { - ts_short_f = new Touchstone(1); - *ts_short_f = Touchstone::fromFile(SOLT.short_f.file.toStdString()); - ts_short_f->reduceTo1Port(SOLT.short_f.Sparam); - } - if(SOLT.load_f.useMeasurements) { - ts_load_f = new Touchstone(1); - *ts_load_f = Touchstone::fromFile(SOLT.load_f.file.toStdString()); - ts_load_f->reduceTo1Port(SOLT.load_f.Sparam); - } - if(SOLT.Through.useMeasurements) { - ts_through = new Touchstone(2); - *ts_through = Touchstone::fromFile(SOLT.Through.file.toStdString()); - ts_through->reduceTo2Port(SOLT.Through.Sparam1, SOLT.Through.Sparam2); - } - ts_cached = true; + return true; // TODO delete function } diff --git a/Software/PC_Application/Calibration/calkit.h b/Software/PC_Application/Calibration/calkit.h index bd094f6..5f3c5da 100644 --- a/Software/PC_Application/Calibration/calkit.h +++ b/Software/PC_Application/Calibration/calkit.h @@ -3,6 +3,7 @@ #include "touchstone.h" #include "Util/qpointervariant.h" +#include "calstandard.h" #include #include @@ -19,9 +20,7 @@ public: this->manufacturer = other.manufacturer; this->serialnumber = other.serialnumber; this->description = other.description; - this->SOLT = other.SOLT; - this->TRL = other.TRL; - this->startDialogWithSOLT = other.startDialogWithSOLT; + this->standards = other.standards; return *this; } @@ -53,146 +52,14 @@ public: bool isTRLReflectionShort() const; private: - void TransformPathsToRelative(QFileInfo d); - void TransformPathsToAbsolute(QFileInfo d); - QString manufacturer, serialnumber, description; - // SOLT standard definitions - struct { - using Open = struct { - double Z0, delay, loss, C0, C1, C2, C3; - QString file; - bool useMeasurements; - int Sparam; - }; - Open open_m, open_f; - using Short = struct { - double Z0, delay, loss, L0, L1, L2, L3; - QString file; - bool useMeasurements; - int Sparam; - }; - Short short_m, short_f; - using Load = struct { - double resistance, Z0, delay, Cparallel, Lseries; - QString file; - bool useMeasurements; - int Sparam; - }; - Load load_m, load_f; - bool loadModelCFirst; - struct { - double Z0, delay, loss; - QString file; - bool useMeasurements; - int Sparam1, Sparam2; - } Through; - bool separate_male_female; - } SOLT; - struct { - struct { - double Z0; - } Through; - struct { - bool isShort; - } Reflection; - struct { - double delay, minFreq, maxFreq; - } Line; - } TRL; - bool startDialogWithSOLT; - - Touchstone *ts_open_m, *ts_short_m, *ts_load_m; - Touchstone *ts_open_f, *ts_short_f, *ts_load_f; - Touchstone *ts_through; - bool ts_cached; + std::vector standards; const std::vector descr = {{ {&manufacturer, "Manufacturer", ""}, {&serialnumber, "Serialnumber", ""}, {&description, "Description", ""}, - - {&SOLT.open_m.Z0, "SOLT.Open.Param.Z0", 50.0}, - {&SOLT.open_m.delay, "SOLT.Open.Param.Delay", 0.0}, - {&SOLT.open_m.loss, "SOLT.Open.Param.Loss", 0.0}, - {&SOLT.open_m.C0, "SOLT.Open.Param.C0", 0.0}, - {&SOLT.open_m.C1, "SOLT.Open.Param.C1", 0.0}, - {&SOLT.open_m.C2, "SOLT.Open.Param.C2", 0.0}, - {&SOLT.open_m.C3, "SOLT.Open.Param.C3", 0.0}, - {&SOLT.open_m.useMeasurements, "SOLT.Open.Measurements.Use", false}, - {&SOLT.open_m.file, "SOLT.Open.Measurements.File", ""}, - {&SOLT.open_m.Sparam, "SOLT.Open.Measurements.Port", 0}, - {&SOLT.open_f.Z0, "SOLT.Open.Param.Z0_Female", 50.0}, - {&SOLT.open_f.delay, "SOLT.Open.Param.Delay_Female", 0.0}, - {&SOLT.open_f.loss, "SOLT.Open.Param.Loss_Female", 0.0}, - {&SOLT.open_f.C0, "SOLT.Open.Param.C0_Female", 0.0}, - {&SOLT.open_f.C1, "SOLT.Open.Param.C1_Female", 0.0}, - {&SOLT.open_f.C2, "SOLT.Open.Param.C2_Female", 0.0}, - {&SOLT.open_f.C3, "SOLT.Open.Param.C3_Female", 0.0}, - {&SOLT.open_f.useMeasurements, "SOLT.Open.Measurements.Use_Female", false}, - {&SOLT.open_f.file, "SOLT.Open.Measurements.File_Female", ""}, - {&SOLT.open_f.Sparam, "SOLT.Open.Measurements.Port_Female", 0}, - - {&SOLT.short_m.Z0, "SOLT.Short.Param.Z0", 50.0}, - {&SOLT.short_m.delay, "SOLT.Short.Param.Delay", 0.0}, - {&SOLT.short_m.loss, "SOLT.Short.Param.Loss", 0.0}, - {&SOLT.short_m.L0, "SOLT.Short.Param.L0", 0.0}, - {&SOLT.short_m.L1, "SOLT.Short.Param.L1", 0.0}, - {&SOLT.short_m.L2, "SOLT.Short.Param.L2", 0.0}, - {&SOLT.short_m.L3, "SOLT.Short.Param.L3", 0.0}, - {&SOLT.short_m.useMeasurements, "SOLT.Short.Measurements.Use", false}, - {&SOLT.short_m.file, "SOLT.Short.Measurements.File", ""}, - {&SOLT.short_m.Sparam, "SOLT.Short.Measurements.Port", 0}, - {&SOLT.short_f.Z0, "SOLT.Short.Param.Z0_Female", 50.0}, - {&SOLT.short_f.delay, "SOLT.Short.Param.Delay_Female", 0.0}, - {&SOLT.short_f.loss, "SOLT.Short.Param.Loss_Female", 0.0}, - {&SOLT.short_f.L0, "SOLT.Short.Param.L0_Female", 0.0}, - {&SOLT.short_f.L1, "SOLT.Short.Param.L1_Female", 0.0}, - {&SOLT.short_f.L2, "SOLT.Short.Param.L2_Female", 0.0}, - {&SOLT.short_f.L3, "SOLT.Short.Param.L3_Female", 0.0}, - {&SOLT.short_f.useMeasurements, "SOLT.Short.Measurements.Use_Female", false}, - {&SOLT.short_f.file, "SOLT.Short.Measurements.File_Female", ""}, - {&SOLT.short_f.Sparam, "SOLT.Short.Measurements.Port_Female", 0}, - - {&SOLT.loadModelCFirst, "SOLT.loadModelCFirst", true}, - {&SOLT.load_m.resistance, "SOLT.Load.Param.Resistance", 50.0}, - {&SOLT.load_m.Z0, "SOLT.Load.Param.Z0", 50.0}, - {&SOLT.load_m.delay, "SOLT.Load.Param.Delay", 0.0}, - {&SOLT.load_m.Cparallel, "SOLT.Load.Param.C", 0.0}, - {&SOLT.load_m.Lseries, "SOLT.Load.Param.L", 0.0}, - {&SOLT.load_m.useMeasurements, "SOLT.Load.Measurements.Use", false}, - {&SOLT.load_m.file, "SOLT.Load.Measurements.File", ""}, - {&SOLT.load_m.Sparam, "SOLT.Load.Measurements.Port", 0}, - {&SOLT.load_f.resistance, "SOLT.Load.Param.Resistance_Female", 50.0}, - {&SOLT.load_f.Z0, "SOLT.Load.Param.Z0_Female", 50.0}, - {&SOLT.load_f.delay, "SOLT.Load.Param.Delay_Female", 0.0}, - {&SOLT.load_f.Cparallel, "SOLT.Load.Param.C_Female", 0.0}, - {&SOLT.load_f.Lseries, "SOLT.Load.Param.L_Female", 0.0}, - {&SOLT.load_f.useMeasurements, "SOLT.Load.Measurements.Use_Female", false}, - {&SOLT.load_f.file, "SOLT.Load.Measurements.File_Female", ""}, - {&SOLT.load_f.Sparam, "SOLT.Load.Measurements.Port_Female", 0}, - - {&SOLT.Through.Z0, "SOLT.Through.Param.Z0", 50.0}, - {&SOLT.Through.delay, "SOLT.Through.Param.Delay", 0.0}, - {&SOLT.Through.loss, "SOLT.Through.Param.Loss", 0.0}, - {&SOLT.Through.useMeasurements, "SOLT.Through.Measurements.Use", false}, - {&SOLT.Through.file, "SOLT.Through.Measurements.File", ""}, - {&SOLT.Through.Sparam1, "SOLT.Through.Measurements.Port1", 0}, - {&SOLT.Through.Sparam2, "SOLT.Through.Measurements.Port2", 1}, - - {&SOLT.separate_male_female, "SOLT.SeparateMaleFemale", false}, - - {&TRL.Through.Z0, "TRL.Through.Z0", 50.0}, - {&TRL.Reflection.isShort, "TRL.Reflect.isShort", false}, - {&TRL.Line.delay, "TRL.Line.Delay", 74.0}, - {&TRL.Line.minFreq, "TRL.Line.minFreq", 751000000.0}, - {&TRL.Line.maxFreq, "TRL.Line.maxFreq", 6000000000.0}, - - {&startDialogWithSOLT, "StartDialogWithSOLT", true} }}; - - void clearTouchstoneCache(); - void fillTouchstoneCache(); }; #endif // CALKIT_H diff --git a/Software/PC_Application/Calibration/calkitdialog.cpp b/Software/PC_Application/Calibration/calkitdialog.cpp index a684619..0d14821 100644 --- a/Software/PC_Application/Calibration/calkitdialog.cpp +++ b/Software/PC_Application/Calibration/calkitdialog.cpp @@ -9,192 +9,87 @@ #include #include #include +#include +#include using namespace std; CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) : QDialog(parent), ui(new Ui::CalkitDialog), - open_ok(true), - short_ok(true), - load_ok(true), - through_ok(true), - editKit(c) + kit(c) { ui->setupUi(this); - ui->OpenType->setId(ui->open_coefficients, 0); - ui->OpenType->setId(ui->open_measurement, 1); - - ui->ShortType->setId(ui->short_coefficients, 0); - ui->ShortType->setId(ui->short_measurement, 1); - - ui->LoadType->setId(ui->load_coefficients, 0); - ui->LoadType->setId(ui->load_measurement, 1); - - ui->ThroughType->setId(ui->through_coefficients, 0); - ui->ThroughType->setId(ui->through_measurement, 1); - - ui->open_touchstone->setPorts(1); - ui->short_touchstone->setPorts(1); - ui->load_touchstone->setPorts(1); - ui->through_touchstone->setPorts(2); - - ui->short_Z0->setUnit("Ω"); - ui->open_Z0->setUnit("Ω"); - ui->load_resistance->setUnit("Ω"); - ui->load_Z0->setUnit("Ω"); - ui->load_parC->setUnit("F"); - ui->load_parC->setPrefixes("fpnum "); - ui->load_serL->setUnit("H"); - ui->load_serL->setPrefixes("fpnum "); - - // Same setup for female standards - ui->OpenType_f->setId(ui->open_coefficients_f, 0); - ui->OpenType_f->setId(ui->open_measurement_f, 1); - - ui->ShortType_f->setId(ui->short_coefficients_f, 0); - ui->ShortType_f->setId(ui->short_measurement_f, 1); - - ui->LoadType_f->setId(ui->load_coefficients_f, 0); - ui->LoadType_f->setId(ui->load_measurement_f, 1); - - ui->open_touchstone_f->setPorts(1); - ui->short_touchstone_f->setPorts(1); - ui->load_touchstone_f->setPorts(1); - - ui->short_Z0_f->setUnit("Ω"); - ui->open_Z0_f->setUnit("Ω"); - ui->load_resistance_f->setUnit("Ω"); - ui->load_Z0_f->setUnit("Ω"); - ui->load_parC_f->setUnit("F"); - ui->load_parC_f->setPrefixes("fpnum "); - ui->load_serL_f->setUnit("H"); - ui->load_serL_f->setPrefixes("fpnum "); - - ui->through_Z0->setUnit("Ω"); - - ui->TRL_through_Z0->setUnit("Ω"); - ui->TRL_line_max->setUnit("Hz"); - ui->TRL_line_max->setPrecision(4); - ui->TRL_line_max->setPrefixes(" kMG"); - ui->TRL_line_min->setUnit("Hz"); - ui->TRL_line_min->setPrecision(4); - ui->TRL_line_min->setPrefixes(" kMG"); - - editKit.clearTouchstoneCache(); - ownKit = editKit; - - connect(ui->cbStandardDefinition, qOverload(&QComboBox::currentIndexChanged), [=](int index){ - if (index == 0) { - // common definition, hide tab bars, set all to male tab - ui->mf_short->setCurrentIndex(0); - ui->mf_short->tabBar()->hide(); - ui->mf_open->setCurrentIndex(0); - ui->mf_open->tabBar()->hide(); - ui->mf_load->setCurrentIndex(0); - ui->mf_load->tabBar()->hide(); - } else { - // separate definitions for male/female standards - ui->mf_short->tabBar()->show(); - ui->mf_open->tabBar()->show(); - ui->mf_load->tabBar()->show(); - } - }); - updateEntries(); - connect(ui->TRL_line_min, &SIUnitEdit::valueChanged, [=](double newval){ - ownKit.TRL.Line.minFreq = newval; - updateEntries(); - }); - connect(ui->TRL_line_max, &SIUnitEdit::valueChanged, [=](double newval){ - ownKit.TRL.Line.maxFreq = newval; - updateEntries(); - }); - connect(ui->TRL_line_delay, &QLineEdit::editingFinished, [=](){ - ownKit.TRL.Line.delay = ui->TRL_line_delay->value(); - updateEntries(); + connect(ui->bDelete, &QPushButton::clicked, [=](){ + auto row = ui->list->currentRow(); + if(row >= 0) { + delete kit.standards[row]; + kit.standards.erase(kit.standards.begin() + row); + updateStandardList(); + } }); - auto UpdateStatus = [=]() { - bool ok = true; - if(ui->open_measurement->isChecked() && !ui->open_touchstone->getStatus()) { - ok = false; + connect(ui->bMoveUp, &QPushButton::clicked, [=](){ + auto row = ui->list->currentRow(); + if(row >= 1) { + swap(kit.standards[row], kit.standards[row-1]); + ui->list->setCurrentRow(row-1); + updateStandardList(); } - if(ui->short_measurement->isChecked() && !ui->short_touchstone->getStatus()) { - ok = false; - } - if(ui->load_measurement->isChecked() && !ui->load_touchstone->getStatus()) { - ok = false; - } - if(ui->open_measurement_f->isChecked() && !ui->open_touchstone_f->getStatus()) { - ok = false; - } - if(ui->short_measurement_f->isChecked() && !ui->short_touchstone_f->getStatus()) { - ok = false; - } - if(ui->load_measurement_f->isChecked() && !ui->load_touchstone_f->getStatus()) { - ok = false; - } - if(ui->through_measurement->isChecked() && !ui->through_touchstone->getStatus()) { - ok = false; - } - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok); - ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(ok); - }; + }); - connect(ui->open_touchstone, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->short_touchstone, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->load_touchstone, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->open_touchstone_f, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->short_touchstone_f, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->load_touchstone_f, &TouchstoneImport::statusChanged, UpdateStatus); - connect(ui->through_touchstone, &TouchstoneImport::statusChanged, UpdateStatus); + connect(ui->bMoveDown, &QPushButton::clicked, [=](){ + auto row = ui->list->currentRow(); + if(row < ui->list->count() - 1) { + swap(kit.standards[row], kit.standards[row+1]); + ui->list->setCurrentRow(row+1); + updateStandardList(); + } + }); - connect(ui->OpenType, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->ShortType, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->LoadType, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->OpenType_f, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->ShortType_f, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->LoadType_f, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); - }); - connect(ui->ThroughType, qOverload(&QButtonGroup::buttonClicked), [=](int) { - UpdateStatus(); + connect(ui->list, &QListWidget::currentRowChanged, this, &CalkitDialog::updateListEditButtons); + + auto addMenu = new QMenu(); + for(auto t : CalStandard::Virtual::availableTypes()) { + auto action = new QAction(CalStandard::Virtual::TypeToString(t)); + connect(action, &QAction::triggered, [=](){ + auto newStandard = CalStandard::Virtual::create(t); + if(newStandard) { + kit.standards.push_back(newStandard); + updateStandardList(); + // start the edit dialog of the newly created standard + kit.standards.back()->edit(bind(&CalkitDialog::updateStandardList, this)); + } + }); + addMenu->addAction(action); + } + + ui->bAdd->setMenu(addMenu); + + connect(ui->list, &QListWidget::doubleClicked, [=](const QModelIndex &index){ + if(!index.isValid()) { + return; + } + kit.standards[index.row()]->edit(bind(&CalkitDialog::updateStandardList, this)); }); connect(ui->buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, [this]() { parseEntries(); - editKit = ownKit; - editKit.clearTouchstoneCache(); emit settingsChanged(); }); connect(ui->buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, [this]() { parseEntries(); - editKit = ownKit; - editKit.clearTouchstoneCache(); emit settingsChanged(); accept(); }); - connect(ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, [this]() { - reject(); - }); connect(ui->buttonBox->button(QDialogButtonBox::Open), &QPushButton::clicked, [=](){ auto filename = QFileDialog::getOpenFileName(this, "Open calibration kit coefficients", "", "Calibration kit files (*.calkit)", nullptr, QFileDialog::DontUseNativeDialog); if(filename.length() > 0) { try { - ownKit = Calkit::fromFile(filename); + kit = Calkit::fromFile(filename); } catch (runtime_error &e) { InformationBox::ShowError("Error", "The calibration kit file could not be parsed (" + QString(e.what()) + ")"); qWarning() << "Parsing of calibration kit failed while opening calibration file: " << e.what(); @@ -207,7 +102,7 @@ CalkitDialog::CalkitDialog(Calkit &c, QWidget *parent) : auto filename = QFileDialog::getSaveFileName(this, "Save calibration kit coefficients", "", "Calibration kit files (*.calkit)", nullptr, QFileDialog::DontUseNativeDialog); if(filename.length() > 0) { parseEntries(); - ownKit.toFile(filename); + kit.toFile(filename); } }); } @@ -217,256 +112,40 @@ CalkitDialog::~CalkitDialog() delete ui; } +void CalkitDialog::updateListEditButtons() +{ + ui->bDelete->setEnabled(ui->list->currentRow() >= 0); + ui->bMoveUp->setEnabled(ui->list->currentRow() >= 1); + ui->bMoveDown->setEnabled(ui->list->currentRow() >= 0 && ui->list->currentRow() < ui->list->count() - 1); +} + void CalkitDialog::parseEntries() { - ownKit.manufacturer = ui->manufacturer->text(); - ownKit.serialnumber = ui->serialnumber->text(); - ownKit.description = ui->description->toPlainText(); - - // type - ownKit.SOLT.open_m.useMeasurements = ui->open_measurement->isChecked(); - ownKit.SOLT.short_m.useMeasurements = ui->short_measurement->isChecked(); - ownKit.SOLT.load_m.useMeasurements = ui->load_measurement->isChecked(); - ownKit.SOLT.open_f.useMeasurements = ui->open_measurement_f->isChecked(); - ownKit.SOLT.short_f.useMeasurements = ui->short_measurement_f->isChecked(); - ownKit.SOLT.load_f.useMeasurements = ui->load_measurement_f->isChecked(); - ownKit.SOLT.Through.useMeasurements = ui->through_measurement->isChecked(); - - // coefficients - ownKit.SOLT.open_m.Z0 = ui->open_Z0->value(); - ownKit.SOLT.open_m.delay = ui->open_delay->value(); - ownKit.SOLT.open_m.loss = ui->open_loss->value(); - ownKit.SOLT.open_m.C0 = ui->open_C0->value(); - ownKit.SOLT.open_m.C1 = ui->open_C1->value(); - ownKit.SOLT.open_m.C2 = ui->open_C2->value(); - ownKit.SOLT.open_m.C3 = ui->open_C3->value(); - - ownKit.SOLT.short_m.Z0 = ui->short_Z0->value(); - ownKit.SOLT.short_m.delay = ui->short_delay->value(); - ownKit.SOLT.short_m.loss = ui->short_loss->value(); - ownKit.SOLT.short_m.L0 = ui->short_L0->value(); - ownKit.SOLT.short_m.L1 = ui->short_L1->value(); - ownKit.SOLT.short_m.L2 = ui->short_L2->value(); - ownKit.SOLT.short_m.L3 = ui->short_L3->value(); - - ownKit.SOLT.loadModelCFirst = ui->load_C_first->isChecked(); - ownKit.SOLT.load_m.resistance = ui->load_resistance->value(); - ownKit.SOLT.load_m.Z0 = ui->load_Z0->value(); - ownKit.SOLT.load_m.delay = ui->load_delay->value(); - ownKit.SOLT.load_m.Cparallel = ui->load_parC->value(); - ownKit.SOLT.load_m.Lseries = ui->load_serL->value(); - - ownKit.SOLT.open_f.Z0 = ui->open_Z0_f->value(); - ownKit.SOLT.open_f.delay = ui->open_delay_f->value(); - ownKit.SOLT.open_f.loss = ui->open_loss_f->value(); - ownKit.SOLT.open_f.C0 = ui->open_C0_f->value(); - ownKit.SOLT.open_f.C1 = ui->open_C1_f->value(); - ownKit.SOLT.open_f.C2 = ui->open_C2_f->value(); - ownKit.SOLT.open_f.C3 = ui->open_C3_f->value(); - - ownKit.SOLT.short_f.Z0 = ui->short_Z0_f->value(); - ownKit.SOLT.short_f.delay = ui->short_delay_f->value(); - ownKit.SOLT.short_f.loss = ui->short_loss_f->value(); - ownKit.SOLT.short_f.L0 = ui->short_L0_f->value(); - ownKit.SOLT.short_f.L1 = ui->short_L1_f->value(); - ownKit.SOLT.short_f.L2 = ui->short_L2_f->value(); - ownKit.SOLT.short_f.L3 = ui->short_L3_f->value(); - - ownKit.SOLT.load_f.resistance = ui->load_resistance_f->value(); - ownKit.SOLT.load_f.Z0 = ui->load_Z0_f->value(); - ownKit.SOLT.load_f.delay = ui->load_delay_f->value(); - ownKit.SOLT.load_f.Cparallel = ui->load_parC_f->value(); - ownKit.SOLT.load_f.Lseries = ui->load_serL_f->value(); - - ownKit.SOLT.Through.Z0 = ui->through_Z0->value(); - ownKit.SOLT.Through.delay = ui->through_delay->value(); - ownKit.SOLT.Through.loss = ui->through_loss->value(); - - ownKit.SOLT.separate_male_female = ui->cbStandardDefinition->currentIndex() == 1; - - // file - ownKit.SOLT.open_m.file = ui->open_touchstone->getFilename(); - ownKit.SOLT.short_m.file = ui->short_touchstone->getFilename(); - ownKit.SOLT.load_m.file = ui->load_touchstone->getFilename(); - ownKit.SOLT.Through.file = ui->through_touchstone->getFilename(); - - ownKit.SOLT.open_m.Sparam = ui->open_touchstone->getPorts()[0]; - ownKit.SOLT.short_m.Sparam = ui->short_touchstone->getPorts()[0]; - ownKit.SOLT.load_m.Sparam = ui->load_touchstone->getPorts()[0]; - ownKit.SOLT.Through.Sparam1 = ui->through_touchstone->getPorts()[0]; - ownKit.SOLT.Through.Sparam2 = ui->through_touchstone->getPorts()[1]; - - ownKit.SOLT.open_f.file = ui->open_touchstone_f->getFilename(); - ownKit.SOLT.short_f.file = ui->short_touchstone_f->getFilename(); - ownKit.SOLT.load_f.file = ui->load_touchstone_f->getFilename(); - - ownKit.SOLT.open_f.Sparam = ui->open_touchstone_f->getPorts()[0]; - ownKit.SOLT.short_f.Sparam = ui->short_touchstone_f->getPorts()[0]; - ownKit.SOLT.load_f.Sparam = ui->load_touchstone_f->getPorts()[0]; - - // TRL - ownKit.TRL.Through.Z0 = ui->TRL_through_Z0->value(); - ownKit.TRL.Reflection.isShort = ui->TRL_R_short->isChecked(); - ownKit.TRL.Line.delay = ui->TRL_line_delay->value(); - ownKit.TRL.Line.minFreq = ui->TRL_line_min->value(); - ownKit.TRL.Line.maxFreq = ui->TRL_line_max->value(); - - ownKit.startDialogWithSOLT = ui->tabWidget->currentIndex() == 0; + kit.manufacturer = ui->manufacturer->text(); + kit.serialnumber = ui->serialnumber->text(); + kit.description = ui->description->toPlainText(); } void CalkitDialog::updateEntries() { - ui->manufacturer->setText(ownKit.manufacturer); - ui->serialnumber->setText(ownKit.serialnumber); - ui->description->setPlainText(ownKit.description); - - // Coefficients - ui->open_Z0->setValueQuiet(ownKit.SOLT.open_m.Z0); - ui->open_delay->setValueQuiet(ownKit.SOLT.open_m.delay); - ui->open_loss->setValueQuiet(ownKit.SOLT.open_m.loss); - ui->open_C0->setValueQuiet(ownKit.SOLT.open_m.C0); - ui->open_C1->setValueQuiet(ownKit.SOLT.open_m.C1); - ui->open_C2->setValueQuiet(ownKit.SOLT.open_m.C2); - ui->open_C3->setValueQuiet(ownKit.SOLT.open_m.C3); - - ui->short_Z0->setValueQuiet(ownKit.SOLT.short_m.Z0); - ui->short_delay->setValueQuiet(ownKit.SOLT.short_m.delay); - ui->short_loss->setValueQuiet(ownKit.SOLT.short_m.loss); - ui->short_L0->setValueQuiet(ownKit.SOLT.short_m.L0); - ui->short_L1->setValueQuiet(ownKit.SOLT.short_m.L1); - ui->short_L2->setValueQuiet(ownKit.SOLT.short_m.L2); - ui->short_L3->setValueQuiet(ownKit.SOLT.short_m.L3); - - ui->load_C_first->setChecked(ownKit.SOLT.loadModelCFirst); - ui->load_L_first->setChecked(!ownKit.SOLT.loadModelCFirst); - ui->load_resistance->setValueQuiet(ownKit.SOLT.load_m.resistance); - ui->load_Z0->setValueQuiet(ownKit.SOLT.load_m.Z0); - ui->load_delay->setValueQuiet(ownKit.SOLT.load_m.delay); - ui->load_parC->setValueQuiet(ownKit.SOLT.load_m.Cparallel); - ui->load_serL->setValueQuiet(ownKit.SOLT.load_m.Lseries); - - ui->open_Z0_f->setValueQuiet(ownKit.SOLT.open_f.Z0); - ui->open_delay_f->setValueQuiet(ownKit.SOLT.open_f.delay); - ui->open_loss_f->setValueQuiet(ownKit.SOLT.open_f.loss); - ui->open_C0_f->setValueQuiet(ownKit.SOLT.open_f.C0); - ui->open_C1_f->setValueQuiet(ownKit.SOLT.open_f.C1); - ui->open_C2_f->setValueQuiet(ownKit.SOLT.open_f.C2); - ui->open_C3_f->setValueQuiet(ownKit.SOLT.open_f.C3); - - ui->short_Z0_f->setValueQuiet(ownKit.SOLT.short_f.Z0); - ui->short_delay_f->setValueQuiet(ownKit.SOLT.short_f.delay); - ui->short_loss_f->setValueQuiet(ownKit.SOLT.short_f.loss); - ui->short_L0_f->setValueQuiet(ownKit.SOLT.short_f.L0); - ui->short_L1_f->setValueQuiet(ownKit.SOLT.short_f.L1); - ui->short_L2_f->setValueQuiet(ownKit.SOLT.short_f.L2); - ui->short_L3_f->setValueQuiet(ownKit.SOLT.short_f.L3); - - ui->load_resistance_f->setValueQuiet(ownKit.SOLT.load_f.resistance); - ui->load_Z0_f->setValueQuiet(ownKit.SOLT.load_f.Z0); - ui->load_delay_f->setValueQuiet(ownKit.SOLT.load_f.delay); - ui->load_parC_f->setValueQuiet(ownKit.SOLT.load_f.Cparallel); - ui->load_serL_f->setValueQuiet(ownKit.SOLT.load_f.Lseries); - - ui->through_Z0->setValueQuiet(ownKit.SOLT.Through.Z0); - ui->through_delay->setValueQuiet(ownKit.SOLT.Through.delay); - ui->through_loss->setValueQuiet(ownKit.SOLT.Through.loss); - - // Measurements - ui->open_touchstone->setFile(ownKit.SOLT.open_m.file); - ui->open_touchstone->selectPort(0, ownKit.SOLT.open_m.Sparam); - - ui->short_touchstone->setFile(ownKit.SOLT.short_m.file); - ui->short_touchstone->selectPort(0, ownKit.SOLT.short_m.Sparam); - - ui->load_touchstone->setFile(ownKit.SOLT.load_m.file); - ui->load_touchstone->selectPort(0, ownKit.SOLT.load_m.Sparam); - - ui->open_touchstone_f->setFile(ownKit.SOLT.open_f.file); - ui->open_touchstone_f->selectPort(0, ownKit.SOLT.open_f.Sparam); - - ui->short_touchstone_f->setFile(ownKit.SOLT.short_f.file); - ui->short_touchstone_f->selectPort(0, ownKit.SOLT.short_f.Sparam); - - ui->load_touchstone_f->setFile(ownKit.SOLT.load_f.file); - ui->load_touchstone_f->selectPort(0, ownKit.SOLT.load_f.Sparam); - - ui->through_touchstone->setFile(ownKit.SOLT.Through.file); - ui->through_touchstone->selectPort(0, ownKit.SOLT.Through.Sparam1); - ui->through_touchstone->selectPort(1, ownKit.SOLT.Through.Sparam2); - - // Type - if (ownKit.SOLT.open_m.useMeasurements) { - ui->open_measurement->click(); - } else { - ui->open_coefficients->click(); - } - - if (ownKit.SOLT.short_m.useMeasurements) { - ui->short_measurement->click(); - } else { - ui->short_coefficients->click(); - } - - if (ownKit.SOLT.load_m.useMeasurements) { - ui->load_measurement->click(); - } else { - ui->load_coefficients->click(); - } - - if (ownKit.SOLT.open_f.useMeasurements) { - ui->open_measurement_f->click(); - } else { - ui->open_coefficients_f->click(); - } - - if (ownKit.SOLT.short_f.useMeasurements) { - ui->short_measurement_f->click(); - } else { - ui->short_coefficients_f->click(); - } - - if (ownKit.SOLT.load_f.useMeasurements) { - ui->load_measurement_f->click(); - } else { - ui->load_coefficients_f->click(); - } - - if (ownKit.SOLT.Through.useMeasurements) { - ui->through_measurement->click(); - } else { - ui->through_coefficients->click(); - } - - if (ownKit.SOLT.separate_male_female) { - ui->cbStandardDefinition->setCurrentIndex(1); - } else { - ui->cbStandardDefinition->setCurrentIndex(0); - } - - // TRL - ui->TRL_through_Z0->setValueQuiet(ownKit.TRL.Through.Z0); - if(ownKit.TRL.Reflection.isShort) { - ui->TRL_R_short->setChecked(true); - } else { - ui->TRL_R_open->setChecked(true); - } - ui->TRL_line_delay->setValueQuiet(ownKit.TRL.Line.delay); - ui->TRL_line_min->setValueQuiet(ownKit.TRL.Line.minFreq); - ui->TRL_line_max->setValueQuiet(ownKit.TRL.Line.maxFreq); - // Check if line length is appropriate for frequencies - auto minDelay = 20.0/(ownKit.TRL.Line.minFreq * 360.0) * 1e12; - auto maxDelay = 160.0/(ownKit.TRL.Line.maxFreq * 360.0) * 1e12; - if(ownKit.TRL.Line.delay < minDelay) { - ui->TRL_line_warning->setText("Line too short, minimum required delay is "+QString::number(minDelay, 'g', 3) + "ps"); - } else if(ownKit.TRL.Line.delay > maxDelay) { - ui->TRL_line_warning->setText("Line too long, maximum allowed delay is "+QString::number(maxDelay, 'g', 3) + "ps"); - } else { - ui->TRL_line_warning->clear(); - } - - if (ownKit.startDialogWithSOLT) { - ui->tabWidget->setCurrentIndex(0); - } else { - ui->tabWidget->setCurrentIndex(1); - } + ui->manufacturer->setText(kit.manufacturer); + ui->serialnumber->setText(kit.serialnumber); + ui->description->setPlainText(kit.description); +} + +void CalkitDialog::updateStandardList() +{ + auto row = ui->list->currentRow(); + ui->list->clear(); + for(auto s : kit.standards) { + ui->list->addItem(s->getDescription()); + } + if(row >= 0) { + if(row < ui->list->count()) { + ui->list->setCurrentRow(row); + } else if(ui->list->count() > 0) { + ui->list->setCurrentRow(ui->list->count() - 1); + } + } + updateListEditButtons(); } diff --git a/Software/PC_Application/Calibration/calkitdialog.h b/Software/PC_Application/Calibration/calkitdialog.h index ff8959f..4e3208a 100644 --- a/Software/PC_Application/Calibration/calkitdialog.h +++ b/Software/PC_Application/Calibration/calkitdialog.h @@ -22,15 +22,15 @@ public: signals: void settingsChanged(); -private: +private slots: + void updateListEditButtons(); +private: void parseEntries(); void updateEntries(); + void updateStandardList(); Ui::CalkitDialog *ui; - bool open_ok, short_ok, load_ok, through_ok; - - Calkit ownKit; - Calkit &editKit; + Calkit &kit; }; #endif // CALKITDIALOG_H diff --git a/Software/PC_Application/Calibration/calkitdialog.ui b/Software/PC_Application/Calibration/calkitdialog.ui index e010eab..6a3bf58 100644 --- a/Software/PC_Application/Calibration/calkitdialog.ui +++ b/Software/PC_Application/Calibration/calkitdialog.ui @@ -9,8 +9,8 @@ 0 0 - 1213 - 637 + 648 + 530 @@ -28,7 +28,7 @@ false - + @@ -85,1272 +85,109 @@ - - - 0 + + + Standards - - - SOLT - - - - - - - - - - - - Standard definition: - - - - - - - 1 - - - - Use one common definition for open/short/load standard - - - - - Use separate male/female definitions for open/short/load standard - - - - - - - - - - - - - - - 16 - - - - Short - - - Qt::AlignCenter - - - - - - - 0 - - - - Male - - - - - - - - Coefficients - - - ShortType - - - - - - - Measurement file - - - ShortType - - - - - - - - - 0 - - - - - - - - - Offset delay [ps]: - - - - - - - - - - Offset loss [GΩ/s]: - - - - - - - - - - <html><head/><body><p>L0 [10<span style=" vertical-align:super;">-12</span>H]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L1 [10<span style=" vertical-align:super;">-24</span>H/Hz]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L2 [10<span style=" vertical-align:super;">-33</span>H/Hz<span style=" vertical-align:super;">2</span>]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L3 [10<span style=" vertical-align:super;">-42</span>H/Hz<span style=" vertical-align:super;">3</span>]:</p></body></html> - - - - - - - - - - true - - - - - - - Z0: - - - - - - - - - - - - - - - - - - - - - Female - - - - - - - - Coefficients - - - ShortType_f - - - - - - - Measurement file - - - ShortType_f - - - - - - - - - 0 - - - - - - - - - Offset delay [ps]: - - - - - - - - - - Offset loss [GΩ/s]: - - - - - - - - - - <html><head/><body><p>L0 [10<span style=" vertical-align:super;">-12</span>H]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L1 [10<span style=" vertical-align:super;">-24</span>H/Hz]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L2 [10<span style=" vertical-align:super;">-33</span>H/Hz<span style=" vertical-align:super;">2</span>]:</p></body></html> - - - - - - - - - - <html><head/><body><p>L3 [10<span style=" vertical-align:super;">-42</span>H/Hz<span style=" vertical-align:super;">3</span>]:</p></body></html> - - - - - - - - - - true - - - - - - - Z0: - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - - - - - - - 16 - - - - Open - - - Qt::AlignCenter - - - - - - - 0 - - - - Male - - - - - - - - Coefficients - - - OpenType - - - - - - - Measurement file - - - OpenType - - - - - - - - - 0 - - - - - - - - - Offset delay [ps]: - - - - - - - - - - Offset loss [GΩ/s]: - - - - - - - - - - C0 [10<sup>-15</sup>F]: - - - - - - - - - - C1 [10<sup>-27</sup>F/Hz]: - - - - - - - - - - C2 [10<sup>-36</sup>F/Hz<sup>2</sup>]: - - - - - - - - - - <html><head/><body><p>C3 [10<span style=" vertical-align:super;">-45</span>F/Hz<span style=" vertical-align:super;">3</span>]:</p></body></html> - - - - - - - - - - true - - - - - - - Z0: - - - - - - - - - - - - - - - - - - - - - Female - - - - - - - - Coefficients - - - OpenType_f - - - - - - - Measurement file - - - OpenType_f - - - - - - - - - 0 - - - - - - - - - Offset delay [ps]: - - - - - - - - - - Offset loss [GΩ/s]: - - - - - - - - - - C0 [10<sup>-15</sup>F]: - - - - - - - - - - C1 [10<sup>-27</sup>F/Hz]: - - - - - - - - - - C2 [10<sup>-36</sup>F/Hz<sup>2</sup>]: - - - - - - - - - - <html><head/><body><p>C3 [10<span style=" vertical-align:super;">-45</span>F/Hz<span style=" vertical-align:super;">3</span>]:</p></body></html> - - - - - - - - - - true - - - - - - - Z0: - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - - - - - - - 16 - - - - Load - - - Qt::AlignCenter - - - - - - - 0 - - - - Male - - - - - - - - Coefficients - - - LoadType - - - - - - - Measurement file - - - LoadType - - - - - - - - - 0 - - - - - - - - - Z0: - - - - - - - true - - - - - - - Offset delay [ps]: - - - - - - - - - - Parallel C: - - - - - - - - - - Series L: - - - - - - - - - - Resistance: - - - - - - - - - - - - - - - - - - - - - - - - Female - - - - - - - - Coefficients - - - LoadType_f - - - - - - - Measurement file - - - LoadType_f - - - - - - - - - 0 - - - - - - - - - Z0: - - - - - - - true - - - - - - - Offset delay [ps]: - - - - - - - - - - Parallel C: - - - - - - - - - - Series L: - - - - - - - - - - Resistance: - - - - - - - - - - - - - - - - - - - - - - - - - - - Load Parameter Model - - - - - - Series L first - - - LoadModel - - - - - - - Shunt C first - - - LoadModel - - - - - - - - - - - - - - - - Qt::Vertical - - - - - - - - - - 16 - - - - Through - - - Qt::AlignCenter - - - - - - - - - Coefficients - - - ThroughType - - - - - - - Measurement file - - - ThroughType - - - - - - - - - 0 - - - - - - - - - Z0: - - - - - - - false - - - - - - - Delay [ps]: - - - - - - - - - - Loss [GΩ/s]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - TRL - - - - - - - - - 0 - 0 - - - - - 16 - - - - Through - - - Qt::AlignCenter - - - - - - - - - Z0 [Ω]: - - - - - - - false - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Vertical - - - - - - - - - - 16 - - - - Reflection - - - Qt::AlignCenter - - - - - - - Short - - - TRL_Rtype - - - - - - - Open - - - TRL_Rtype - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Vertical - - - - - - - - - - 0 - 0 - - - - - 16 - - - - Line - - - Qt::AlignCenter - - - - - - - - - Delay [ps]: - - - - - - - true - - - - - - - - - - Min. frequency: - - - - - - - true - - - - - - - - - - Max. frequency: - - - - - - - true - - - - - - - - - - - - - - - - - 239 - 41 - 41 - - - - - - - - - 239 - 41 - 41 - - - - - - - - - 190 - 190 - 190 - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - + + + + + + + + + + + 0 + 0 + + + + Add + + + + + + + :/icons/add.png:/icons/add.png + + + + + + + false + + + + 0 + 0 + + + + Delete + + + + + + + :/icons/remove.png:/icons/remove.png + + + + + + + false + + + Move up + + + + + + + :/icons/up.png:/icons/up.png + + + + + + + false + + + Move down + + + + + + + :/icons/down.png:/icons/down.png + + + + + + + Qt::Vertical + + + + 18 + 186 + + + + + + + @@ -1359,7 +196,7 @@ Qt::Horizontal - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::Save + QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::Save false @@ -1368,151 +205,8 @@ - - - SIUnitEdit - QLineEdit -
CustomWidgets/siunitedit.h
-
- - TouchstoneImport - QWidget -
CustomWidgets/touchstoneimport.h
- 1 -
-
- - open_Z0 - open_delay - open_loss - open_C0 - open_C1 - open_C2 - - - - - OpenType - buttonClicked(int) - open_stack - setCurrentIndex(int) - - - -1 - -1 - - - 141 - 187 - - - - - ShortType - buttonClicked(int) - short_stack - setCurrentIndex(int) - - - -1 - -1 - - - 420 - 187 - - - - - LoadType - buttonClicked(int) - load_stack - setCurrentIndex(int) - - - -1 - -1 - - - 699 - 187 - - - - - ThroughType - buttonClicked(int) - through_stack - setCurrentIndex(int) - - - -1 - -1 - - - 978 - 187 - - - - - ShortType_f - buttonClicked(int) - short_stack_f - setCurrentIndex(int) - - - -1 - -1 - - - 165 - 442 - - - - - OpenType_f - buttonClicked(int) - open_stack_f - setCurrentIndex(int) - - - -1 - -1 - - - 466 - 442 - - - - - LoadType_f - buttonClicked(int) - load_stack_f - setCurrentIndex(int) - - - -1 - -1 - - - 767 - 442 - - - - - - - - - - - - - - - + + + + diff --git a/Software/PC_Application/Calibration/calstandard.cpp b/Software/PC_Application/Calibration/calstandard.cpp index 39ccf82..44f8a72 100644 --- a/Software/PC_Application/Calibration/calstandard.cpp +++ b/Software/PC_Application/Calibration/calstandard.cpp @@ -2,11 +2,33 @@ #include "ui_CalStandardOpenEditDialog.h" #include "ui_CalStandardShortEditDialog.h" #include "ui_CalStandardLoadEditDialog.h" +#include "ui_CalStandardThroughEditDialog.h" #include "unit.h" using namespace std; using namespace CalStandard; +Virtual *Virtual::create(Virtual::Type type) +{ + Virtual *ret = nullptr; + switch(type) { + case Type::Open: ret = new Open; break; + case Type::Short: ret = new Short; break; + case Type::Load: ret = new Load; break; + case Type::Through: ret = new Through; break; + } + return ret; +} + +std::vector Virtual::availableTypes() +{ + std::vector ret; + for(int i=0;i<(int) Type::Last;i++) { + ret.push_back((Type) i); + } + return ret; +} + QString Virtual::TypeToString(Virtual::Type type) { switch(type) { @@ -134,7 +156,7 @@ std::complex Open::toS11(double freq) } } -void Open::edit() +void Open::edit(std::function finishedCallback) { auto d = new QDialog; auto ui = new Ui::CalStandardOpenEditDialog; @@ -196,6 +218,9 @@ void Open::edit() C1 = ui->C1->value(); C2 = ui->C2->value(); C3 = ui->C3->value(); + if(finishedCallback) { + finishedCallback(); + } }); d->show(); @@ -246,7 +271,7 @@ std::complex Short::toS11(double freq) } } -void Short::edit() +void Short::edit(std::function finishedCallback) { auto d = new QDialog; auto ui = new Ui::CalStandardShortEditDialog; @@ -308,6 +333,9 @@ void Short::edit() L1 = ui->L1->value(); L2 = ui->L2->value(); L3 = ui->L3->value(); + if(finishedCallback) { + finishedCallback(); + } }); d->show(); @@ -371,7 +399,7 @@ std::complex Load::toS11(double freq) } } -void Load::edit() +void Load::edit(std::function finishedCallback) { auto d = new QDialog; auto ui = new Ui::CalStandardLoadEditDialog; @@ -444,6 +472,9 @@ void Load::edit() Cparallel = ui->parC->value(); Lseries = ui->serL->value(); Cfirst = ui->C_first->isChecked(); + if(finishedCallback) { + finishedCallback(); + } }); d->show(); @@ -513,6 +544,13 @@ void TwoPort::fromJSON(nlohmann::json j) } } +Through::Through() +{ + Z0 = 50.0; + delay = 0.0; + loss = 0.0; +} + Sparam Through::toSparam(double freq) { if(touchstone) { @@ -529,12 +567,81 @@ Sparam Through::toSparam(double freq) } } +void Through::edit(std::function finishedCallback) +{ + auto d = new QDialog; + auto ui = new Ui::CalStandardThroughEditDialog; + ui->setupUi(d); + + ui->name->setText(name); + ui->Z0->setUnit("Ω"); + ui->Z0->setPrecision(2); + ui->Z0->setValue(Z0); + ui->delay->setValue(delay); + ui->loss->setValue(loss); + + auto updateMeasurementLabel = [=](){ + QString label; + if(touchstone) { + label = QString::number(touchstone->points())+" points from "+Unit::ToString(touchstone->minFreq(), "Hz", " kMG")+" to "+Unit::ToString(touchstone->maxFreq(), "Hz", " kMG"); + } else { + label = "No measurements stored yet"; + } + ui->measurementLabel->setText(label); + }; + + QObject::connect(ui->coefficients, &QRadioButton::toggled, [=](bool checked) { + if(checked) { + clearMeasurement(); + } + ui->stackedWidget->setCurrentIndex(checked ? 0 : 1); + }); + QObject::connect(ui->measurement, &QRadioButton::toggled, [=](bool checked) { + updateMeasurementLabel(); + ui->stackedWidget->setCurrentIndex(checked ? 1 : 0); + }); + + QObject::connect(ui->touchstoneImport, &TouchstoneImport::statusChanged, ui->updateFile, &QPushButton::setEnabled); + + ui->touchstoneImport->setPorts(1); + if(touchstone) { + ui->measurement->setChecked(true); + ui->touchstoneImport->setFile(touchstone->getFilename()); + } else { + ui->coefficients->setChecked(true); + } + + QObject::connect(ui->updateFile, &QPushButton::clicked, [=](){ + setMeasurement(ui->touchstoneImport->getTouchstone(), ui->touchstoneImport->getPorts()[0]); + updateMeasurementLabel(); + }); + + QObject::connect(d, &QDialog::accepted, [=](){ + name = ui->name->text(); + Z0 = ui->Z0->value(); + delay = ui->delay->value(); + loss = ui->loss->value(); + if(finishedCallback) { + finishedCallback(); + } + }); + + d->show(); +} + nlohmann::json Through::toJSON() { - + auto j = TwoPort::toJSON(); + j["Z0"] = Z0; + j["delay"] = delay; + j["loss"] = loss; + return j; } void Through::fromJSON(nlohmann::json j) { - + TwoPort::fromJSON(j); + Z0 = j.value("Z0", 50.0); + delay = j.value("delay", 0.0); + loss = j.value("loss", 0.0); } diff --git a/Software/PC_Application/Calibration/calstandard.h b/Software/PC_Application/Calibration/calstandard.h index 2e00d63..920c2e3 100644 --- a/Software/PC_Application/Calibration/calstandard.h +++ b/Software/PC_Application/Calibration/calstandard.h @@ -6,6 +6,7 @@ #include "Tools/parameters.h" #include +#include namespace CalStandard { @@ -28,6 +29,7 @@ public: static Virtual* create(Type type); + static std::vector availableTypes(); static QString TypeToString(Type type); static Type TypeFromString(QString s); @@ -35,7 +37,7 @@ public: double minFrequency() {return minFreq;} double maxFrequency() {return maxFreq;} - virtual void edit() = 0; + virtual void edit(std::function finishedCallback) = 0; virtual QString getDescription(); virtual nlohmann::json toJSON() override; @@ -74,7 +76,7 @@ public: Open(); virtual std::complex toS11(double freq) override; - virtual void edit() override; + virtual void edit(std::function finishedCallback = nullptr) override; virtual Type getType() override {return Type::Open;} virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; @@ -88,7 +90,7 @@ public: Short(); virtual std::complex toS11(double freq) override; - virtual void edit() override; + virtual void edit(std::function finishedCallback = nullptr) override; virtual Type getType() override {return Type::Short;} virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; @@ -102,7 +104,7 @@ public: Load(); virtual std::complex toS11(double freq) override; - virtual void edit() override; + virtual void edit(std::function finishedCallback = nullptr) override; virtual Type getType() override {return Type::Load;} virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; @@ -135,6 +137,7 @@ public: Through(); virtual Sparam toSparam(double freq) override; + virtual void edit(std::function finishedCallback = nullptr) override; virtual Type getType() override {return Type::Through;} virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; diff --git a/Software/PC_Application/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI.pro index 53599b6..e084622 100644 --- a/Software/PC_Application/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI.pro @@ -277,6 +277,7 @@ FORMS += \ Calibration/CalStandardLoadEditDialog.ui \ Calibration/CalStandardOpenEditDialog.ui \ Calibration/CalStandardShortEditDialog.ui \ + Calibration/CalStandardThroughEditDialog.ui \ Calibration/addamplitudepointsdialog.ui \ Calibration/amplitudecaldialog.ui \ Calibration/automaticamplitudedialog.ui \