LibreVNA/Software/PC_Application/Calibration/calibration.h

193 lines
6.2 KiB
C
Raw Normal View History

#ifndef CALIBRATION_H
#define CALIBRATION_H
#include "Device/device.h"
2021-10-21 19:00:34 +08:00
#include "calkit.h"
#include "Traces/tracemodel.h"
#include <complex>
#include <vector>
#include <map>
#include <iostream>
#include <iomanip>
#include <QDateTime>
#include <savable.h>
class Calibration : public Savable
{
public:
Calibration();
enum class Measurement {
Port1Open,
Port1Short,
Port1Load,
Port2Open,
Port2Short,
Port2Load,
Isolation,
Through,
Line,
2021-04-16 01:24:11 +08:00
Last,
};
enum class Standard {
Open,
Short,
Load,
Through,
Any,
};
static Standard getPort1Standard(Measurement m);
static Standard getPort2Standard(Measurement m);
void clearMeasurements();
void clearMeasurements(std::set<Measurement> types);
void clearMeasurement(Measurement type);
2022-08-05 02:12:15 +08:00
void addMeasurement(Measurement type, VirtualDevice::VNAMeasurement &d);
void addMeasurements(std::set<Measurement> types, VirtualDevice::VNAMeasurement &d);
enum class Type {
Port1SOL,
Port2SOL,
FullSOLT,
TransmissionNormalization,
TRL,
None,
2021-04-16 01:24:11 +08:00
Last,
};
bool calculationPossible(Type type);
bool constructErrorTerms(Type type);
void resetErrorTerms();
2022-08-05 02:12:15 +08:00
void correctMeasurement(VirtualDevice::VNAMeasurement &d);
void correctTraces(Trace &S11, Trace &S12, Trace &S21, Trace &S22);
enum class InterpolationType {
Unchanged, // Nothing has changed, settings and calibration points match
Exact, // Every frequency point in settings has an exact calibration point (but there are more calibration points outside of the sweep)
Interpolate, // Every point in the sweep can be interpolated between two calibration points
Extrapolate, // At least one point in sweep is outside of the calibration and has to be extrapolated
NoCalibration, // No calibration available
};
2021-07-10 04:26:44 +08:00
InterpolationType getInterpolation(double f_start, double f_stop, int points);
2021-04-16 01:24:11 +08:00
static Measurement MeasurementFromString(QString s);
static QString MeasurementToString(Measurement m);
2021-04-16 01:24:11 +08:00
static Type TypeFromString(QString s);
static QString TypeToString(Type t);
class MeasurementInfo {
public:
QString name, prerequisites;
double fmin, fmax;
unsigned int points;
QDateTime timestamp;
};
static const std::vector<Type> Types();
const std::vector<Measurement> Measurements(Type type = Type::None, bool optional_included = true);
MeasurementInfo getMeasurementInfo(Measurement m);
friend std::istream& operator >> (std::istream &in, Calibration& c);
int nPoints() {
return points.size();
}
std::vector<Trace*> getErrorTermTraces();
std::vector<Trace*> getMeasurementTraces();
bool openFromFile(QString filename = QString());
bool saveToFile(QString filename = QString());
Type getType() const;
Calkit& getCalibrationKit();
void setCalibrationKit(const Calkit &value);
enum class PortStandard {
Male,
Female,
};
void setPortStandard(int port, PortStandard standard);
PortStandard getPortStandard(int port);
2021-12-03 05:41:51 +08:00
bool getThroughZeroLength() const;
void setThroughZeroLength(bool value);
QString getCurrentCalibrationFile();
double getMinFreq();
double getMaxFreq();
int getNumPoints();
nlohmann::json toJSON() override;
void fromJSON(nlohmann::json j) override;
private:
void construct12TermPoints();
void constructPort1SOL();
void constructPort2SOL();
void constructTransmissionNormalization();
void constructTRL();
bool SanityCheckSamples(const std::vector<Measurement> &requiredMeasurements);
class Point
{
public:
double frequency;
// Forward error terms
std::complex<double> fe00, fe11, fe10e01, fe10e32, fe22, fe30, fex;
// Reverse error terms
std::complex<double> re33, re11, re23e32, re23e01, re22, re03, rex;
};
2022-08-05 02:12:15 +08:00
Point getCalibrationPoint(VirtualDevice::VNAMeasurement &d);
/*
* Constructs directivity, match and tracking correction factors from measurements of three distinct impedances
* Normally, an open, short and load are used (with ideal reflection coefficients of 1, -1 and 0 respectively).
* The actual reflection coefficients can be passed on as optional arguments to take into account the non-ideal
* calibration kit.
*/
void computeSOL(std::complex<double> s_m,
std::complex<double> o_m,
std::complex<double> l_m,
std::complex<double> &directivity,
std::complex<double> &match,
std::complex<double> &tracking,
std::complex<double> o_c = std::complex<double>(1.0, 0),
std::complex<double> s_c = std::complex<double>(-1.0, 0),
std::complex<double> l_c = std::complex<double>(0, 0));
void computeIsolation(std::complex<double> x0_m,
std::complex<double> x1_m,
std::complex<double> reverse_match,
std::complex<double> reverse_tracking,
std::complex<double> reverse_directivity,
std::complex<double> x0,
std::complex<double> x1,
std::complex<double> &internal_isolation,
std::complex<double> &external_isolation);
std::complex<double> correctSOL(std::complex<double> measured,
std::complex<double> directivity,
std::complex<double> match,
std::complex<double> tracking);
class MeasurementData {
public:
QDateTime timestamp;
2022-08-05 02:12:15 +08:00
std::vector<VirtualDevice::VNAMeasurement> datapoints;
};
Type type;
std::map<Measurement, MeasurementData> measurements;
double minFreq, maxFreq;
std::vector<Point> points;
Calkit kit;
QString descriptiveCalName();
2020-12-01 01:16:33 +08:00
QString currentCalFile;
PortStandard port1Standard, port2Standard;
2021-12-03 05:41:51 +08:00
bool throughZeroLength;
};
#endif // CALIBRATION_H