#include "librecaldialog.h" #include "ui_librecaldialog.h" #include "caldevice.h" #include "usbdevice.h" #include "Device/virtualdevice.h" #include #include using namespace std; LibreCALDialog::LibreCALDialog(Calibration *cal) : QDialog(nullptr), ui(new Ui::LibreCALDialog), cal(cal), device(nullptr), busy(false) { ui->setupUi(this); createPortAssignmentUI(); connect(this, &LibreCALDialog::portAssignmentChanged, this, &LibreCALDialog::updateCalibrationStartStatus); connect(ui->cbDevice, &QComboBox::currentTextChanged, [=](QString text) { if(device) { delete device; } device = new CalDevice(text); if(device) { createPortAssignmentUI(); connect(device, &CalDevice::updateCoefficientsPercent, ui->progressCoeff, &QProgressBar::setValue); connect(device, &CalDevice::updateCoefficientsDone, [=](bool success){ busy = false; if(success) { ui->progressCoeff->setValue(100); ui->lCoefficientStatus->setText("Coefficients loaded."); coeffSet = device->getCoefficientSets()[0]; } else { ui->progressCal->setValue(0); ui->lCoefficientStatus->setText("Failed to load coefficients"); } updateCalibrationStartStatus(); }); ui->cbCoefficients->clear(); ui->cbCoefficients->addItem("Select..."); for(auto c : device->getCoefficientSetNames()) { ui->cbCoefficients->addItem(c); } ui->cbCoefficients->setEnabled(true); } else { ui->cbCoefficients->clear(); ui->cbCoefficients->setEnabled(false); ui->start->setEnabled(false); } }); connect(ui->cbCoefficients, &QComboBox::currentTextChanged, [=](){ // no coefficient set selected ui->progressCoeff->setValue(0); ui->lCoefficientStatus->setText("No coefficients loaded"); coeffSet = CalDevice::CoefficientSet(); updateCalibrationStartStatus(); if(ui->cbCoefficients->currentIndex() > 0) { if(!device) { qWarning() << "Coefficients selected without connected device"; return; } busy = true; ui->lCoefficientStatus->setText("Loading coefficients..."); device->loadCoefficientSets({ui->cbCoefficients->currentText()}); } }); auto deviceList = USBDevice::GetDevices(); for(auto device : deviceList) { ui->cbDevice->addItem(device); } connect(this, &QDialog::finished, [=](){ delete device; device = nullptr; }); connect(ui->start, &QPushButton::clicked, this, &LibreCALDialog::startCalibration); updateCalibrationStartStatus(); updateDeviceStatus(); connect(&updateTimer, &QTimer::timeout, this, &LibreCALDialog::updateDeviceStatus); updateTimer.start(1000); } LibreCALDialog::~LibreCALDialog() { delete device; delete ui; } void LibreCALDialog::updateCalibrationStartStatus() { bool canStart = true; QString status = "Ready to start"; if(!device) { status = "Not connected to a LibreCAL device."; canStart = false; } set usedCalPorts; if(canStart) { // Check port mapping for duplicate entries (and at least one used port) for(auto port : portAssignment) { if(port < 1) { // skip unused ports continue; } if(usedCalPorts.count(port)) { status = "LibreCAL port "+QString::number(port)+" is assigned to multiple VNA ports."; canStart = false; break; } else { usedCalPorts.insert(port); } } } if(canStart) { // at least one port must be used if(usedCalPorts.size() == 0) { status = "At least one port must be assigned."; canStart = false; } } if(canStart) { // check if coefficients have been loaded if(coeffSet.opens.size() != device->getNumPorts()) { status = "Coefficients not loaded"; canStart = false; } } if(canStart) { double coeffMinFreq = numeric_limits::max(); double coeffMaxFreq = numeric_limits::lowest(); auto checkCoefficient = [&](CalDevice::CoefficientSet::Coefficient *c) -> bool { if(c->t.points() == 0) { return false; } else { if(c->t.minFreq() < coeffMinFreq) { coeffMinFreq = c->t.minFreq(); } if(c->t.maxFreq() > coeffMaxFreq) { coeffMaxFreq = c->t.maxFreq(); } return true; } }; // check if coefficients for all ports are available for(auto i : usedCalPorts) { // Check if OSL coefficients are there if(!checkCoefficient(coeffSet.opens[i-1])) { status = "Open coefficient for LibreCAL port "+QString::number(i)+" is missing."; canStart = false; break; } if(!checkCoefficient(coeffSet.shorts[i-1])) { status = "Short coefficient for LibreCAL port "+QString::number(i)+" is missing."; canStart = false; break; } if(!checkCoefficient(coeffSet.loads[i-1])) { status = "Load coefficient for LibreCAL port "+QString::number(i)+" is missing."; canStart = false; break; } for(auto j : usedCalPorts) { if(j <= i) { continue; } if(!checkCoefficient(coeffSet.getThrough(i,j))) { status = "Through coefficient for LibreCAL port "+QString::number(i)+" to "+QString::number(j)+" is missing."; canStart = false; break; } } } } ui->lCalibrationStatus->setText(status); ui->start->setEnabled(canStart); if(canStart) { ui->lCalibrationStatus->setStyleSheet("QLabel { color : black; }"); } else { ui->lCalibrationStatus->setStyleSheet("QLabel { color : red; }"); } } void LibreCALDialog::updateDeviceStatus() { if(!device) { ui->lDeviceStatus->setText("No LibreCAL connected"); ui->lDeviceStatus->setStyleSheet("QLabel { color : red; }"); return; } if(busy) { // can't update while busy reading coefficients return; } if(device->stabilized()) { ui->lDeviceStatus->setText("LibreCAL ready for calibration"); ui->lDeviceStatus->setStyleSheet("QLabel { color : black; }"); } else { ui->lDeviceStatus->setText("Heating up, please wait with calibration"); ui->lDeviceStatus->setStyleSheet("QLabel { color : orange; }"); } } void LibreCALDialog::startCalibration() { ui->cbDevice->setEnabled(false); ui->cbCoefficients->setEnabled(false); ui->start->setEnabled(false); ui->lCalibrationStatus->setText("Creating calibration kit from coefficients..."); auto& kit = cal->getKit(); kit = Calkit::fromLibreCAL(device, coeffSet); } void LibreCALDialog::createPortAssignmentUI() { auto layout = static_cast(ui->assignmentBox->layout()); // Clear any possible previous elements portAssignment.clear(); while(layout->rowCount() > 1) { layout->removeRow(1); } auto vnaPorts = VirtualDevice::getInfo(VirtualDevice::getConnected()).ports; portAssignment.resize(vnaPorts, 0); auto calPorts = 0; if(device) { calPorts = device->getNumPorts(); } QStringList choices = {"Unused"}; for(int i=1;i<=calPorts;i++) { choices.push_back("Port "+QString::number(i)); } for(int p = 1;p<=vnaPorts;p++) { auto label = new QLabel("Port "+QString::number(p)+":"); auto comboBox = new QComboBox(); comboBox->addItems(choices); connect(comboBox, qOverload(&QComboBox::currentIndexChanged), [=](){ portAssignment[p-1] = comboBox->currentIndex(); emit portAssignmentChanged(); }); // try to set the default comboBox->setCurrentIndex(p); layout->addRow(label, comboBox); } }