##// END OF EJS Templates
Adds read compatibility for local AMDA server...
Alexandre Leroux -
r1121:98220c931c83
parent child
Show More
@@ -1,76 +1,79
1 1 #ifndef SCIQLOP_AMDARESULTPARSERDEFS_H
2 2 #define SCIQLOP_AMDARESULTPARSERDEFS_H
3 3
4 4 #include <QtCore/QRegularExpression>
5 5 #include <QtCore/QString>
6 6 #include <QtCore/QVariantHash>
7 7
8 8 // ////////// //
9 9 // Properties //
10 10 // ////////// //
11 11
12 12 /// Alias to represent properties read in the header of AMDA file
13 13 using Properties = QVariantHash;
14 14
15 15 extern const QString END_TIME_PROPERTY;
16 16 extern const QString FILL_VALUE_PROPERTY;
17 17 extern const QString MAX_BANDS_PROPERTY;
18 18 extern const QString MIN_BANDS_PROPERTY;
19 19 extern const QString MAX_SAMPLING_PROPERTY;
20 20 extern const QString MIN_SAMPLING_PROPERTY;
21 21 extern const QString START_TIME_PROPERTY;
22 22 extern const QString X_AXIS_UNIT_PROPERTY;
23 23 extern const QString Y_AXIS_UNIT_PROPERTY;
24 24 extern const QString VALUES_UNIT_PROPERTY;
25 25
26 26 // /////////////////// //
27 27 // Regular expressions //
28 28 // /////////////////// //
29 29
30 30 // AMDA V2
31 31 // /// Regex to find the header of the data in the file. This header indicates the end of comments
32 32 // in the file
33 33 // const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
34 34
35 35 // AMDA V2
36 36 // /// ... PARAMETER_UNITS : nT ...
37 37 // /// ... PARAMETER_UNITS:nT ...
38 38 // /// ... PARAMETER_UNITS: mΒ² ...
39 39 // /// ... PARAMETER_UNITS : m/s ...
40 40 // const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
41 41
42 42 /// Regex to find x-axis unit in a line. Examples of valid lines:
43 43 /// ... - Units : nT - ...
44 44 /// ... -Units:nT- ...
45 45 /// ... -Units: mΒ²- ...
46 46 /// ... - Units : m/s - ...
47 47 extern const QRegularExpression DEFAULT_X_AXIS_UNIT_REGEX;
48 48
49 /// Alternative regex to find x-axis unit in a line
50 extern const QRegularExpression ALTERNATIVE_X_AXIS_UNIT_REGEX;
51
49 52 /// Regex to find end time of data in a line for a spectrogram
50 53 extern const QRegularExpression SPECTROGRAM_END_TIME_REGEX;
51 54
52 55 /// Regex to find fill value used in a line for a spectrogram
53 56 extern const QRegularExpression SPECTROGRAM_FILL_VALUE_REGEX;
54 57
55 58 /// Regex to find max bands in a line for a spectrogram
56 59 extern const QRegularExpression SPECTROGRAM_MAX_BANDS_REGEX;
57 60
58 61 /// Regex to find min bands in a line for a spectrogram
59 62 extern const QRegularExpression SPECTROGRAM_MIN_BANDS_REGEX;
60 63
61 64 /// Regex to find max x-axis sampling in a line for a spectrogram
62 65 extern const QRegularExpression SPECTROGRAM_MAX_SAMPLING_REGEX;
63 66
64 67 /// Regex to find min x-axis sampling in a line for a spectrogram
65 68 extern const QRegularExpression SPECTROGRAM_MIN_SAMPLING_REGEX;
66 69
67 70 /// Regex to find start time of data in a line for a spectrogram
68 71 extern const QRegularExpression SPECTROGRAM_START_TIME_REGEX;
69 72
70 73 /// Regex to find y-axis unit in a line for a spectrogram
71 74 extern const QRegularExpression SPECTROGRAM_Y_AXIS_UNIT_REGEX;
72 75
73 76 /// Regex to find values unit in a line for a spectrogram
74 77 extern const QRegularExpression SPECTROGRAM_VALUES_UNIT_REGEX;
75 78
76 79 #endif // SCIQLOP_AMDARESULTPARSERDEFS_H
@@ -1,42 +1,49
1 1 #include "AmdaResultParserDefs.h"
2 2
3 3 const QString END_TIME_PROPERTY = QStringLiteral("endTime");
4 4 const QString FILL_VALUE_PROPERTY = QStringLiteral("fillValue");
5 5 const QString MAX_BANDS_PROPERTY = QStringLiteral("maxBands");
6 6 const QString MIN_BANDS_PROPERTY = QStringLiteral("minBands");
7 7 const QString MAX_SAMPLING_PROPERTY = QStringLiteral("maxSampling");
8 8 const QString MIN_SAMPLING_PROPERTY = QStringLiteral("minSampling");
9 9 const QString START_TIME_PROPERTY = QStringLiteral("startTime");
10 10 const QString X_AXIS_UNIT_PROPERTY = QStringLiteral("xAxisUnit");
11 11 const QString Y_AXIS_UNIT_PROPERTY = QStringLiteral("yAxisUnit");
12 12 const QString VALUES_UNIT_PROPERTY = QStringLiteral("valuesUnit");
13 13
14 namespace {
15
16 const auto PARAMETER_UNITS_REGEX
17 = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.*)")};
18 }
19
14 20 const QRegularExpression DEFAULT_X_AXIS_UNIT_REGEX
15 21 = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
16 22
23 const QRegularExpression ALTERNATIVE_X_AXIS_UNIT_REGEX = PARAMETER_UNITS_REGEX;
24
17 25 const QRegularExpression SPECTROGRAM_END_TIME_REGEX
18 26 = QRegularExpression{QStringLiteral("\\s*INTERVAL_STOP\\s*:\\s*(.*)")};
19 27
20 28 const QRegularExpression SPECTROGRAM_FILL_VALUE_REGEX
21 29 = QRegularExpression{QStringLiteral("\\s*PARAMETER_FILL_VALUE\\s*:\\s*(.*)")};
22 30
23 31 const QRegularExpression SPECTROGRAM_MAX_BANDS_REGEX
24 32 = QRegularExpression{QStringLiteral("\\s*PARAMETER_TABLE_MAX_VALUES\\[0\\]\\s*:\\s*(.*)")};
25 33
26 34 const QRegularExpression SPECTROGRAM_MIN_BANDS_REGEX
27 35 = QRegularExpression{QStringLiteral("\\s*PARAMETER_TABLE_MIN_VALUES\\[0\\]\\s*:\\s*(.*)")};
28 36
29 37 const QRegularExpression SPECTROGRAM_MAX_SAMPLING_REGEX
30 38 = QRegularExpression{QStringLiteral("\\s*DATASET_MAX_SAMPLING\\s*:\\s*(.*)")};
31 39
32 40 const QRegularExpression SPECTROGRAM_MIN_SAMPLING_REGEX
33 41 = QRegularExpression{QStringLiteral("\\s*DATASET_MIN_SAMPLING\\s*:\\s*(.*)")};
34 42
35 43 const QRegularExpression SPECTROGRAM_START_TIME_REGEX
36 44 = QRegularExpression{QStringLiteral("\\s*INTERVAL_START\\s*:\\s*(.*)")};
37 45
38 46 const QRegularExpression SPECTROGRAM_Y_AXIS_UNIT_REGEX
39 47 = QRegularExpression{QStringLiteral("\\s*PARAMETER_TABLE_UNITS\\[0\\]\\s*:\\s*(.*)")};
40 48
41 const QRegularExpression SPECTROGRAM_VALUES_UNIT_REGEX
42 = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.*)")};
49 const QRegularExpression SPECTROGRAM_VALUES_UNIT_REGEX = PARAMETER_UNITS_REGEX;
@@ -1,423 +1,432
1 1 #include "AmdaResultParserHelper.h"
2 2
3 3 #include <Common/DateUtils.h>
4 4 #include <Common/SortUtils.h>
5 5
6 6 #include <Data/DataSeriesUtils.h>
7 7 #include <Data/ScalarSeries.h>
8 8 #include <Data/SpectrogramSeries.h>
9 9 #include <Data/Unit.h>
10 10 #include <Data/VectorSeries.h>
11 11
12 12 #include <QtCore/QDateTime>
13 13 #include <QtCore/QRegularExpression>
14 14
15 15 #include <functional>
16 16
17 17 Q_LOGGING_CATEGORY(LOG_AmdaResultParserHelper, "AmdaResultParserHelper")
18 18
19 19 namespace {
20 20
21 21 // ///////// //
22 22 // Constants //
23 23 // ///////// //
24 24
25 25 /// Separator between values in a result line
26 26 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
27 27
28 28 /// Format for dates in result files
29 29 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
30 30
31 31 // /////// //
32 32 // Methods //
33 33 // /////// //
34 34
35 35 /**
36 36 * Checks that the properties contain a specific unit and that this unit is valid
37 37 * @param properties the properties map in which to search unit
38 38 * @param key the key to search for the unit in the properties
39 39 * @param errorMessage the error message to log in case the unit is invalid
40 40 * @return true if the unit is valid, false it it's invalid or was not found in the properties
41 41 */
42 42 bool checkUnit(const Properties &properties, const QString &key, const QString &errorMessage)
43 43 {
44 44 auto unit = properties.value(key).value<Unit>();
45 45 if (unit.m_Name.isEmpty()) {
46 46 qCWarning(LOG_AmdaResultParserHelper()) << errorMessage;
47 47 return false;
48 48 }
49 49
50 50 return true;
51 51 }
52 52
53 53 QDateTime dateTimeFromString(const QString &stringDate) noexcept
54 54 {
55 55 #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
56 56 return QDateTime::fromString(stringDate, Qt::ISODateWithMs);
57 57 #else
58 58 return QDateTime::fromString(stringDate, DATE_FORMAT);
59 59 #endif
60 60 }
61 61
62 62 /// Converts a string date to a double date
63 63 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
64 64 double doubleDate(const QString &stringDate) noexcept
65 65 {
66 66 // Format: yyyy-MM-ddThh:mm:ss.zzz
67 67 auto dateTime = dateTimeFromString(stringDate);
68 68 dateTime.setTimeSpec(Qt::UTC);
69 69 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
70 70 : std::numeric_limits<double>::quiet_NaN();
71 71 }
72 72
73 73 /**
74 74 * Reads a line from the AMDA file and tries to extract a x-axis data and value data from it
75 75 * @param xAxisData the vector in which to store the x-axis data extracted
76 76 * @param valuesData the vector in which to store the value extracted
77 77 * @param line the line to read to extract the property
78 78 * @param valuesIndexes indexes of insertion of read values. For example, if the line contains three
79 79 * columns of values, and valuesIndexes are {2, 0, 1}, the value of the third column will be read
80 80 * and inserted first, then the value of the first column, and finally the value of the second
81 81 * column.
82 82 * @param fillValue value that tags an invalid data. For example, if fillValue is -1 and a read
83 83 * value is -1, then this value is considered as invalid and converted to NaN
84 84 */
85 85 void tryReadResult(std::vector<double> &xAxisData, std::vector<double> &valuesData,
86 86 const QString &line, const std::vector<int> &valuesIndexes,
87 87 double fillValue = std::numeric_limits<double>::quiet_NaN())
88 88 {
89 89 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
90 90
91 91 // Checks that the line contains expected number of values + x-axis value
92 92 if (static_cast<size_t>(lineData.size()) == valuesIndexes.size() + 1) {
93 93 // X : the data is converted from date to double (in secs)
94 94 auto x = doubleDate(lineData.at(0));
95 95
96 96 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
97 97 if (!std::isnan(x)) {
98 98 xAxisData.push_back(x);
99 99
100 100 // Values
101 101 for (auto valueIndex : valuesIndexes) {
102 102 bool valueOk;
103 103 // we use valueIndex + 1 to skip column 0 (x-axis value)
104 104 auto value = lineData.at(valueIndex + 1).toDouble(&valueOk);
105 105
106 106 if (!valueOk) {
107 107 qCWarning(LOG_AmdaResultParserHelper())
108 108 << QObject::tr(
109 109 "Value from (line %1, column %2) is invalid and will be "
110 110 "converted to NaN")
111 111 .arg(line, valueIndex);
112 112 value = std::numeric_limits<double>::quiet_NaN();
113 113 }
114 114
115 115 // Handles fill value
116 116 if (!std::isnan(fillValue) && !std::isnan(value) && fillValue == value) {
117 117 value = std::numeric_limits<double>::quiet_NaN();
118 118 }
119 119
120 120 valuesData.push_back(value);
121 121 }
122 122 }
123 123 else {
124 124 qCWarning(LOG_AmdaResultParserHelper())
125 125 << QObject::tr("Can't retrieve results from line %1: x is invalid").arg(line);
126 126 }
127 127 }
128 128 else {
129 129 qCWarning(LOG_AmdaResultParserHelper())
130 130 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
131 131 }
132 132 }
133 133
134 134 /**
135 135 * Reads a line from the AMDA file and tries to extract a property from it
136 136 * @param properties the properties map in which to put the property extracted from the line
137 137 * @param key the key to which the property is added in the properties map
138 138 * @param line the line to read to extract the property
139 * @param regex the expected regex to extract the property. If the line matches this regex, the
139 * @param regexes the expected regexes to extract the property. If the line matches one regex, the
140 140 * property is generated
141 141 * @param fun the function used to generate the property
142 142 * @return true if the property could be generated, false if the line does not match the regex, or
143 143 * if a property has already been generated for the key
144 144 */
145 145 template <typename GeneratePropertyFun>
146 146 bool tryReadProperty(Properties &properties, const QString &key, const QString &line,
147 const QRegularExpression &regex, GeneratePropertyFun fun)
147 const std::vector<QRegularExpression> &regexes, GeneratePropertyFun fun)
148 148 {
149 149 if (properties.contains(key)) {
150 150 return false;
151 151 }
152 152
153 auto match = regex.match(line);
154 if (match.hasMatch()) {
153 // Searches for a match among all possible regexes
154 auto hasMatch = false;
155 for (auto regexIt = regexes.cbegin(), end = regexes.cend(); regexIt != end && !hasMatch;
156 ++regexIt) {
157 auto match = regexIt->match(line);
158 auto hasMatch = match.hasMatch();
159 if (hasMatch) {
155 160 properties.insert(key, fun(match));
156 161 }
162 }
157 163
158 return match.hasMatch();
164 return hasMatch;
159 165 }
160 166
161 167 /**
162 168 * Reads a line from the AMDA file and tries to extract a data from it. Date is converted to double
163 169 * @sa tryReadProperty()
164 170 */
165 171 bool tryReadDate(Properties &properties, const QString &key, const QString &line,
166 const QRegularExpression &regex, bool timeUnit = false)
172 const std::vector<QRegularExpression> &regexes, bool timeUnit = false)
167 173 {
168 return tryReadProperty(properties, key, line, regex, [timeUnit](const auto &match) {
174 return tryReadProperty(properties, key, line, regexes, [timeUnit](const auto &match) {
169 175 return QVariant::fromValue(doubleDate(match.captured(1)));
170 176 });
171 177 }
172 178
173 179 /**
174 180 * Reads a line from the AMDA file and tries to extract a double from it
175 181 * @sa tryReadProperty()
176 182 */
177 183 bool tryReadDouble(Properties &properties, const QString &key, const QString &line,
178 const QRegularExpression &regex)
184 const std::vector<QRegularExpression> &regexes)
179 185 {
180 return tryReadProperty(properties, key, line, regex, [](const auto &match) {
186 return tryReadProperty(properties, key, line, regexes, [](const auto &match) {
181 187 bool ok;
182 188
183 189 // If the value can't be converted to double, it is set to NaN
184 190 auto doubleValue = match.captured(1).toDouble(&ok);
185 191 if (!ok) {
186 192 doubleValue = std::numeric_limits<double>::quiet_NaN();
187 193 }
188 194
189 195 return QVariant::fromValue(doubleValue);
190 196 });
191 197 }
192 198
193 199 /**
194 200 * Reads a line from the AMDA file and tries to extract a vector of doubles from it
195 201 * @param sep the separator of double values in the line
196 202 * @sa tryReadProperty()
197 203 */
198 204 bool tryReadDoubles(Properties &properties, const QString &key, const QString &line,
199 const QRegularExpression &regex, const QString &sep = QStringLiteral(","))
205 const std::vector<QRegularExpression> &regexes,
206 const QString &sep = QStringLiteral(","))
200 207 {
201 return tryReadProperty(properties, key, line, regex, [sep](const auto &match) {
208 return tryReadProperty(properties, key, line, regexes, [sep](const auto &match) {
202 209 std::vector<double> doubleValues{};
203 210
204 211 // If the value can't be converted to double, it is set to NaN
205 212 auto values = match.captured(1).split(sep);
206 213 for (auto value : values) {
207 214 bool ok;
208 215
209 216 auto doubleValue = value.toDouble(&ok);
210 217 if (!ok) {
211 218 doubleValue = std::numeric_limits<double>::quiet_NaN();
212 219 }
213 220
214 221 doubleValues.push_back(doubleValue);
215 222 }
216 223
217 224 return QVariant::fromValue(doubleValues);
218 225 });
219 226 }
220 227
221 228 /**
222 229 * Reads a line from the AMDA file and tries to extract a unit from it
223 230 * @sa tryReadProperty()
224 231 */
225 232 bool tryReadUnit(Properties &properties, const QString &key, const QString &line,
226 const QRegularExpression &regex, bool timeUnit = false)
233 const std::vector<QRegularExpression> &regexes, bool timeUnit = false)
227 234 {
228 return tryReadProperty(properties, key, line, regex, [timeUnit](const auto &match) {
235 return tryReadProperty(properties, key, line, regexes, [timeUnit](const auto &match) {
229 236 return QVariant::fromValue(Unit{match.captured(1), timeUnit});
230 237 });
231 238 }
232 239
233 240 } // namespace
234 241
235 242 // ////////////////// //
236 243 // ScalarParserHelper //
237 244 // ////////////////// //
238 245
239 246 bool ScalarParserHelper::checkProperties()
240 247 {
241 248 return checkUnit(m_Properties, X_AXIS_UNIT_PROPERTY,
242 249 QObject::tr("The x-axis unit could not be found in the file"));
243 250 }
244 251
245 252 std::shared_ptr<IDataSeries> ScalarParserHelper::createSeries()
246 253 {
247 254 return std::make_shared<ScalarSeries>(std::move(m_XAxisData), std::move(m_ValuesData),
248 255 m_Properties.value(X_AXIS_UNIT_PROPERTY).value<Unit>(),
249 256 m_Properties.value(VALUES_UNIT_PROPERTY).value<Unit>());
250 257 }
251 258
252 259 void ScalarParserHelper::readPropertyLine(const QString &line)
253 260 {
254 tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line, DEFAULT_X_AXIS_UNIT_REGEX, true);
261 tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line,
262 {DEFAULT_X_AXIS_UNIT_REGEX, ALTERNATIVE_X_AXIS_UNIT_REGEX}, true);
255 263 }
256 264
257 265 void ScalarParserHelper::readResultLine(const QString &line)
258 266 {
259 267 tryReadResult(m_XAxisData, m_ValuesData, line, valuesIndexes());
260 268 }
261 269
262 270 std::vector<int> ScalarParserHelper::valuesIndexes() const
263 271 {
264 272 // Only one value to read
265 273 static auto result = std::vector<int>{0};
266 274 return result;
267 275 }
268 276
269 277 // /////////////////////// //
270 278 // SpectrogramParserHelper //
271 279 // /////////////////////// //
272 280
273 281 bool SpectrogramParserHelper::checkProperties()
274 282 {
275 283 // Generates y-axis data from bands extracted (take the middle of the intervals)
276 284 auto minBands = m_Properties.value(MIN_BANDS_PROPERTY).value<std::vector<double> >();
277 285 auto maxBands = m_Properties.value(MAX_BANDS_PROPERTY).value<std::vector<double> >();
278 286
279 287 if (minBands.size() < 2 || minBands.size() != maxBands.size()) {
280 288 qCWarning(LOG_AmdaResultParserHelper()) << QObject::tr(
281 289 "Can't generate y-axis data from bands extracted: bands intervals are invalid");
282 290 return false;
283 291 }
284 292
285 293 std::transform(
286 294 minBands.begin(), minBands.end(), maxBands.begin(), std::back_inserter(m_YAxisData),
287 295 [](const auto &minValue, const auto &maxValue) { return (minValue + maxValue) / 2.; });
288 296
289 297 // Generates values indexes, i.e. the order in which each value will be retrieved (in ascending
290 298 // order of the associated bands)
291 299 m_ValuesIndexes = SortUtils::sortPermutation(m_YAxisData, std::less<double>());
292 300
293 301 // Sorts y-axis data accoding to the ascending order
294 302 m_YAxisData = SortUtils::sort(m_YAxisData, 1, m_ValuesIndexes);
295 303
296 304 // Sets fill value
297 305 m_FillValue = m_Properties.value(FILL_VALUE_PROPERTY).value<double>();
298 306
299 307 return true;
300 308 }
301 309
302 310 std::shared_ptr<IDataSeries> SpectrogramParserHelper::createSeries()
303 311 {
304 312 // Before creating the series, we handle its data holes
305 313 handleDataHoles();
306 314
307 315 return std::make_shared<SpectrogramSeries>(
308 316 std::move(m_XAxisData), std::move(m_YAxisData), std::move(m_ValuesData),
309 317 Unit{"t", true}, // x-axis unit is always a time unit
310 318 m_Properties.value(Y_AXIS_UNIT_PROPERTY).value<Unit>(),
311 319 m_Properties.value(VALUES_UNIT_PROPERTY).value<Unit>(),
312 320 m_Properties.value(MIN_SAMPLING_PROPERTY).value<double>());
313 321 }
314 322
315 323 void SpectrogramParserHelper::readPropertyLine(const QString &line)
316 324 {
317 325 // Set of functions to test on the line to generate a property. If a function is valid (i.e. a
318 326 // property has been generated for the line), the line is treated as processed and the other
319 327 // functions are not called
320 328 std::vector<std::function<bool()> > functions{
321 329 // values unit
322 330 [&] {
323 331 return tryReadUnit(m_Properties, VALUES_UNIT_PROPERTY, line,
324 SPECTROGRAM_VALUES_UNIT_REGEX);
332 {SPECTROGRAM_VALUES_UNIT_REGEX});
325 333 },
326 334 // y-axis unit
327 335 [&] {
328 336 return tryReadUnit(m_Properties, Y_AXIS_UNIT_PROPERTY, line,
329 SPECTROGRAM_Y_AXIS_UNIT_REGEX);
337 {SPECTROGRAM_Y_AXIS_UNIT_REGEX});
330 338 },
331 339 // min sampling
332 340 [&] {
333 341 return tryReadDouble(m_Properties, MIN_SAMPLING_PROPERTY, line,
334 SPECTROGRAM_MIN_SAMPLING_REGEX);
342 {SPECTROGRAM_MIN_SAMPLING_REGEX});
335 343 },
336 344 // max sampling
337 345 [&] {
338 346 return tryReadDouble(m_Properties, MAX_SAMPLING_PROPERTY, line,
339 SPECTROGRAM_MAX_SAMPLING_REGEX);
347 {SPECTROGRAM_MAX_SAMPLING_REGEX});
340 348 },
341 349 // fill value
342 350 [&] {
343 351 return tryReadDouble(m_Properties, FILL_VALUE_PROPERTY, line,
344 SPECTROGRAM_FILL_VALUE_REGEX);
352 {SPECTROGRAM_FILL_VALUE_REGEX});
345 353 },
346 354 // min bounds of each band
347 355 [&] {
348 356 return tryReadDoubles(m_Properties, MIN_BANDS_PROPERTY, line,
349 SPECTROGRAM_MIN_BANDS_REGEX);
357 {SPECTROGRAM_MIN_BANDS_REGEX});
350 358 },
351 359 // max bounds of each band
352 360 [&] {
353 361 return tryReadDoubles(m_Properties, MAX_BANDS_PROPERTY, line,
354 SPECTROGRAM_MAX_BANDS_REGEX);
362 {SPECTROGRAM_MAX_BANDS_REGEX});
355 363 },
356 364 // start time of data
357 365 [&] {
358 366 return tryReadDate(m_Properties, START_TIME_PROPERTY, line,
359 SPECTROGRAM_START_TIME_REGEX);
367 {SPECTROGRAM_START_TIME_REGEX});
360 368 },
361 369 // end time of data
362 370 [&] {
363 return tryReadDate(m_Properties, END_TIME_PROPERTY, line, SPECTROGRAM_END_TIME_REGEX);
371 return tryReadDate(m_Properties, END_TIME_PROPERTY, line, {SPECTROGRAM_END_TIME_REGEX});
364 372 }};
365 373
366 374 for (auto function : functions) {
367 375 // Stops at the first function that is valid
368 376 if (function()) {
369 377 return;
370 378 }
371 379 }
372 380 }
373 381
374 382 void SpectrogramParserHelper::readResultLine(const QString &line)
375 383 {
376 384 tryReadResult(m_XAxisData, m_ValuesData, line, m_ValuesIndexes, m_FillValue);
377 385 }
378 386
379 387 void SpectrogramParserHelper::handleDataHoles()
380 388 {
381 389 // Fills data holes according to the max resolution found in the AMDA file
382 390 auto resolution = m_Properties.value(MAX_SAMPLING_PROPERTY).value<double>();
383 391 auto fillValue = m_Properties.value(FILL_VALUE_PROPERTY).value<double>();
384 392 auto minBound = m_Properties.value(START_TIME_PROPERTY).value<double>();
385 393 auto maxBound = m_Properties.value(END_TIME_PROPERTY).value<double>();
386 394
387 395 DataSeriesUtils::fillDataHoles(m_XAxisData, m_ValuesData, resolution, fillValue, minBound,
388 396 maxBound);
389 397 }
390 398
391 399 // ////////////////// //
392 400 // VectorParserHelper //
393 401 // ////////////////// //
394 402
395 403 bool VectorParserHelper::checkProperties()
396 404 {
397 405 return checkUnit(m_Properties, X_AXIS_UNIT_PROPERTY,
398 406 QObject::tr("The x-axis unit could not be found in the file"));
399 407 }
400 408
401 409 std::shared_ptr<IDataSeries> VectorParserHelper::createSeries()
402 410 {
403 411 return std::make_shared<VectorSeries>(std::move(m_XAxisData), std::move(m_ValuesData),
404 412 m_Properties.value(X_AXIS_UNIT_PROPERTY).value<Unit>(),
405 413 m_Properties.value(VALUES_UNIT_PROPERTY).value<Unit>());
406 414 }
407 415
408 416 void VectorParserHelper::readPropertyLine(const QString &line)
409 417 {
410 tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line, DEFAULT_X_AXIS_UNIT_REGEX, true);
418 tryReadUnit(m_Properties, X_AXIS_UNIT_PROPERTY, line,
419 {DEFAULT_X_AXIS_UNIT_REGEX, ALTERNATIVE_X_AXIS_UNIT_REGEX}, true);
411 420 }
412 421
413 422 void VectorParserHelper::readResultLine(const QString &line)
414 423 {
415 424 tryReadResult(m_XAxisData, m_ValuesData, line, valuesIndexes());
416 425 }
417 426
418 427 std::vector<int> VectorParserHelper::valuesIndexes() const
419 428 {
420 429 // 3 values to read, in order in the file (x, y, z)
421 430 static auto result = std::vector<int>{0, 1, 2};
422 431 return result;
423 432 }
General Comments 0
You need to be logged in to leave comments. Login now