v2.0.0
Loading...
Searching...
No Matches
fine_calibration.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "fine_calibration.h"
18
19//=============================================================================================================
20// QT INCLUDES
21//=============================================================================================================
22
23#include <QFile>
24#include <QTextStream>
25#include <QDebug>
26#include <QRegularExpression>
27
28//=============================================================================================================
29// USED NAMESPACES
30//=============================================================================================================
31
32using namespace UTILSLIB;
33using namespace Eigen;
34
35//=============================================================================================================
36// DEFINE MEMBER METHODS
37//=============================================================================================================
38
40{
42
43 QFile file(sPath);
44 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
45 qWarning() << "[FineCalibration::read] Cannot open file:" << sPath;
46 return cal;
47 }
48
49 QTextStream in(&file);
50 while (!in.atEnd()) {
51 QString line = in.readLine().trimmed();
52 if (line.isEmpty() || line.startsWith('#')) {
53 continue;
54 }
55
56 const QStringList parts = line.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts);
57 if (parts.size() != 14 && parts.size() != 16) {
58 qWarning() << "[FineCalibration::read] Skipping malformed line:" << line;
59 continue;
60 }
61
62 FineCalEntry entry;
63 bool ok = false;
64 entry.chNumber = QString(parts[0]).remove(QStringLiteral("MEG")).toInt(&ok);
65 VectorXd values(parts.size() - 1);
66 for (int k = 1; ok && k < parts.size(); ++k) {
67 values(k - 1) = parts[k].toDouble(&ok);
68 }
69 if (!ok) {
70 qWarning() << "[FineCalibration::read] Skipping malformed line:" << line;
71 continue;
72 }
73 entry.position = values.head<3>();
74 entry.orientation = Map<const Matrix<double, 3, 3, RowMajor>>(values.data() + 3);
75 entry.imbalance = values.tail(values.size() - 12);
76
77 cal.addEntry(entry);
78 }
79
80 file.close();
81 return cal;
82}
83
84//=============================================================================================================
85
86bool FineCalibration::write(const QString& sPath) const
87{
88 QFile file(sPath);
89 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
90 qWarning() << "[FineCalibration::write] Cannot open file for writing:" << sPath;
91 return false;
92 }
93
94 QTextStream out(&file);
95 for (const auto& entry : m_entries) {
96 out << QString("%1").arg(entry.chNumber, 4, 10, QChar('0'));
97 const Matrix<double, 3, 3, RowMajor> axes = entry.orientation;
98 for (const double v : {entry.position(0), entry.position(1), entry.position(2)}) {
99 out << ' ' << QString::number(v, 'f', 6);
100 }
101 for (int k = 0; k < 9; ++k) {
102 out << ' ' << QString::number(axes.data()[k], 'f', 6);
103 }
104 for (Index k = 0; k < entry.imbalance.size(); ++k) {
105 out << ' ' << QString::number(entry.imbalance(k), 'f', 6);
106 }
107 out << '\n';
108 }
109
110 file.close();
111 return true;
112}
113
114//=============================================================================================================
115
116bool FineCalibration::findEntry(int chNumber, FineCalEntry& entry) const
117{
118 for (const auto& e : m_entries) {
119 if (e.chNumber == chNumber) {
120 entry = e;
121 return true;
122 }
123 }
124 return false;
125}
126
127//=============================================================================================================
128
130{
131 VectorXd gains = VectorXd::Ones(m_entries.size());
132 for (int i = 0; i < m_entries.size(); ++i) {
133 if (m_entries[i].chNumber % 10 == 1) {
134 gains(i) = m_entries[i].imbalance(0);
135 }
136 }
137 return gains;
138}
139
140//=============================================================================================================
141
143{
144 MatrixXd imb = MatrixXd::Zero(m_entries.size(), 3);
145 for (int i = 0; i < m_entries.size(); ++i) {
146 if (m_entries[i].chNumber % 10 != 1) {
147 imb.row(i).head(m_entries[i].imbalance.size()) = m_entries[i].imbalance.transpose();
148 }
149 }
150 return imb;
151}
Fine calibration data for SSS.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Per-sensor fine calibration entry.
Eigen::VectorXd imbalance
Eigen::Matrix3d orientation
bool findEntry(int chNumber, FineCalEntry &entry) const
Find entry by channel number.
Eigen::MatrixXd imbalanceMatrix() const
Gradiometer imbalance terms.
bool write(const QString &sPath) const
Write fine calibration to a .dat file.
Eigen::VectorXd gainVector() const
Magnetometer calibration factors.
void addEntry(const FineCalEntry &entry)
Add an entry.
static FineCalibration read(const QString &sPath)
Read a fine calibration file (.dat format).