##// END OF EJS Templates
Improves controls when reading results
Alexandre Leroux -
r394:4b7007448469
parent child
Show More
@@ -1,103 +1,132
1 1 #include "AmdaResultParser.h"
2 2
3 3 #include <Data/ScalarSeries.h>
4 4
5 5 #include <QDateTime>
6 6 #include <QFile>
7 7 #include <QRegularExpression>
8 8
9 9 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
10 10
11 11 namespace {
12 12
13 13 /// Format for dates in result files
14 14 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
15 15
16 /// Separator between values in a result line
17 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
18
16 19 /// Regex to find unit in a line. Examples of valid lines:
17 20 /// ... - Units : nT - ...
18 21 /// ... -Units:nT- ...
19 22 /// ... -Units: mΒ²- ...
20 23 /// ... - Units : m/s - ...
21 24 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
22 25
23 /// @todo ALX
26 /// Converts a string date to a double date
27 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
24 28 double doubleDate(const QString &stringDate) noexcept
25 29 {
26 30 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
27 return dateTime.toMSecsSinceEpoch() / 1000.;
31 return dateTime.isValid() ? (dateTime.toMSecsSinceEpoch() / 1000.)
32 : std::numeric_limits<double>::quiet_NaN();
28 33 }
29 34
30 35 /**
31 36 * Reads stream to retrieve x-axis unit
32 37 * @param stream the stream to read
33 38 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
34 39 * error occured during reading
35 40 */
36 41 Unit readXAxisUnit(QTextStream &stream)
37 42 {
38 43 QString line{};
39 44
40 45 if (stream.readLineInto(&line)) {
41 46 auto match = UNIT_REGEX.match(line);
42 47 if (match.hasMatch()) {
43 48 return Unit{match.captured(1), true};
44 49 }
45 50 else {
46 51 qCWarning(LOG_AmdaResultParser())
47 52 << QObject::tr("Can't read unit: invalid line %1").arg(line);
48 53 }
49 54 }
50 55 else {
51 56 qCWarning(LOG_AmdaResultParser()) << QObject::tr("Can't read unit: end of file");
52 57 }
53 58
54 59 // Error cases
55 60 return Unit{{}, true};
56 61 }
57 62
63 /**
64 * Reads stream to retrieve results
65 * @param stream the stream to read
66 * @return the pair of vectors x-axis data/values data that has been read in the stream
67 */
68 QPair<QVector<double>, QVector<double> > readResults(QTextStream &stream)
69 {
70 auto xData = QVector<double>{};
71 auto valuesData = QVector<double>{};
72
73 QString line{};
74 while (stream.readLineInto(&line)) {
75 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
76 if (lineData.size() == 2) {
77 // X : the data is converted from date to double (in secs)
78 auto x = doubleDate(lineData.at(0));
79
80 // Value
81 bool valueOk;
82 auto value = lineData.at(1).toDouble(&valueOk);
83
84 // Adds result only if x and value are valid
85 if (!std::isnan(x) && !std::isnan(value) && valueOk) {
86 xData.push_back(x);
87 valuesData.push_back(value);
88 }
89 else {
90 qCWarning(LOG_AmdaResultParser())
91 << QObject::tr(
92 "Can't retrieve results from line %1: x and/or value are invalid")
93 .arg(line);
94 }
95 }
96 else {
97 qCWarning(LOG_AmdaResultParser())
98 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
99 }
100 }
101
102 return qMakePair(std::move(xData), std::move(valuesData));
103 }
104
58 105 } // namespace
59 106
60 107 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath) noexcept
61 108 {
62 109 QFile file{filePath};
63 110
64 111 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
65 112 qCCritical(LOG_AmdaResultParser())
66 113 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
67 114 .arg(filePath, file.errorString());
68 115 return nullptr;
69 116 }
70 117
71 auto xData = QVector<double>{};
72 auto valuesData = QVector<double>{};
73
74 118 QTextStream stream{&file};
75 119
76 120 // Ignore first two lines (comments lines)
77 121 stream.readLine();
78 122 stream.readLine();
79 123
80 QString line{};
81
82 124 // Reads x-axis unit
83 125 auto xAxisUnit = readXAxisUnit(stream);
84 126
85 127 // Reads results
86 auto lineRegex = QRegExp{QStringLiteral("\\s+")};
87 while (stream.readLineInto(&line)) {
88 auto lineData = line.split(lineRegex, QString::SkipEmptyParts);
89 if (lineData.size() == 2) {
90 // X : the data is converted from date to double (in secs)
91 xData.push_back(doubleDate(lineData.at(0)));
92
93 // Value
94 valuesData.push_back(lineData.at(1).toDouble());
95 }
96 else {
97 /// @todo ALX : log
98 }
99 }
128 auto results = readResults(stream);
100 129
101 return std::make_shared<ScalarSeries>(std::move(xData), std::move(valuesData), xAxisUnit,
102 Unit{});
130 return std::make_shared<ScalarSeries>(std::move(results.first), std::move(results.second),
131 xAxisUnit, Unit{});
103 132 }
General Comments 0
You need to be logged in to leave comments. Login now