##// END OF EJS Templates
Run request canceling when unit isn"t found in the file. Clean log.
Run request canceling when unit isn"t found in the file. Clean log.

File last commit:

r832:4ab17865bd43
r832:4ab17865bd43
Show More
AmdaResultParser.cpp
240 lines | 8.0 KiB | text/x-c | CppLexer
/ plugins / amda / src / AmdaResultParser.cpp
Alexandre Leroux
Amda provider (3)...
r380 #include "AmdaResultParser.h"
Alexandre Leroux
Passes TimeWidget in UTC...
r489 #include <Common/DateUtils.h>
Alexandre Leroux
Amda provider (3)...
r380 #include <Data/ScalarSeries.h>
Alexandre Leroux
Updates data series creation according to the value type (vector or scalar)
r565 #include <Data/VectorSeries.h>
Alexandre Leroux
Amda provider (3)...
r380
#include <QDateTime>
#include <QFile>
Alexandre Leroux
Reads x-axis unit in result file
r393 #include <QRegularExpression>
Alexandre Leroux
Amda provider (3)...
r380
Add the cmath include missing
r400 #include <cmath>
Alexandre Leroux
Amda provider (3)...
r380 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
namespace {
Alexandre Leroux
Handles "Not found" error for AMDA result parser
r446 /// Message in result file when the file was not found on server
const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
Alexandre Leroux
Improves controls when reading results
r394 /// Separator between values in a result line
const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
Alexandre Leroux
Changes way to retrieve unit
r792 // AMDA V2
// /// Regex to find the header of the data in the file. This header indicates the end of comments
// in
// /// the file
// const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774
/// Format for dates in result files
const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
Alexandre Leroux
Changes way to retrieve unit
r792 // AMDA V2
// /// Regex to find unit in a line. Examples of valid lines:
// /// ... PARAMETER_UNITS : nT ...
// /// ... PARAMETER_UNITS:nT ...
// /// ... PARAMETER_UNITS: m² ...
// /// ... PARAMETER_UNITS : m/s ...
// const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
/// ... - Units : nT - ...
/// ... -Units:nT- ...
/// ... -Units: m²- ...
/// ... - Units : m/s - ...
const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774
QDateTime dateTimeFromString(const QString &stringDate) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
return QDateTime::fromString(stringDate, Qt::ISODateWithMs);
#else
return QDateTime::fromString(stringDate, DATE_FORMAT);
#endif
}
Alexandre Leroux
Reads x-axis unit in result file
r393
Alexandre Leroux
Improves controls when reading results
r394 /// Converts a string date to a double date
/// @return a double that represents the date in seconds, NaN if the string date can't be converted
Alexandre Leroux
Amda provider (3)...
r380 double doubleDate(const QString &stringDate) noexcept
{
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 // Format: yyyy-MM-ddThh:mm:ss.zzz
auto dateTime = dateTimeFromString(stringDate);
Alexandre Leroux
Passes TimeWidget in UTC...
r489 dateTime.setTimeSpec(Qt::UTC);
return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
Alexandre Leroux
Improves controls when reading results
r394 : std::numeric_limits<double>::quiet_NaN();
Alexandre Leroux
Amda provider (3)...
r380 }
Alexandre Leroux
Improves AMDA result parsing...
r492 /// Checks if a line is a comment line
bool isCommentLine(const QString &line)
{
return line.startsWith("#");
}
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564 /// @return the number of lines to be read depending on the type of value passed in parameter
int nbValues(AmdaResultParser::ValueType valueType) noexcept
{
switch (valueType) {
case AmdaResultParser::ValueType::SCALAR:
return 1;
case AmdaResultParser::ValueType::VECTOR:
return 3;
case AmdaResultParser::ValueType::UNKNOWN:
// Invalid case
break;
}
// Invalid cases
qCCritical(LOG_AmdaResultParser())
<< QObject::tr("Can't get the number of values to read: unsupported type");
return 0;
}
Alexandre Leroux
Reads x-axis unit in result file
r393 /**
* Reads stream to retrieve x-axis unit
* @param stream the stream to read
* @return the unit that has been read in the stream, a default unit (time unit with no label) if an
* error occured during reading
*/
Unit readXAxisUnit(QTextStream &stream)
{
QString line{};
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 // Searches unit in the comment lines (as long as the reading has not reached the data header)
Alexandre Leroux
Changes way to retrieve unit
r792 // AMDA V2: while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
while (stream.readLineInto(&line) && isCommentLine(line)) {
Alexandre Leroux
Reads x-axis unit in result file
r393 auto match = UNIT_REGEX.match(line);
if (match.hasMatch()) {
return Unit{match.captured(1), true};
}
}
Alexandre Leroux
Improves AMDA result parsing...
r492 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
Alexandre Leroux
Reads x-axis unit in result file
r393 // Error cases
return Unit{{}, true};
}
Alexandre Leroux
Improves controls when reading results
r394 /**
* Reads stream to retrieve results
* @param stream the stream to read
* @return the pair of vectors x-axis data/values data that has been read in the stream
*/
Alexandre Leroux
Uses std::vector when retrieving Amda results
r733 std::pair<std::vector<double>, std::vector<double> >
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
Alexandre Leroux
Improves controls when reading results
r394 {
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 auto expectedNbValues = nbValues(valueType) + 1;
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564
Alexandre Leroux
Uses std::vector when retrieving Amda results
r733 auto xData = std::vector<double>{};
auto valuesData = std::vector<double>{};
Alexandre Leroux
Improves controls when reading results
r394
QString line{};
Alexandre Leroux
Improves AMDA result parsing...
r492
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 // Skip comment lines
while (stream.readLineInto(&line) && isCommentLine(line)) {
}
if (!stream.atEnd()) {
do {
Alexandre Leroux
Improves AMDA result parsing...
r492 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 if (lineData.size() == expectedNbValues) {
Alexandre Leroux
Improves AMDA result parsing...
r492 // X : the data is converted from date to double (in secs)
auto x = doubleDate(lineData.at(0));
Alexandre Leroux
Updates AMDA result parser to accept NaN values...
r496 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
if (!std::isnan(x)) {
Alexandre Leroux
Improves AMDA result parsing...
r492 xData.push_back(x);
Alexandre Leroux
Updates AMDA result parser to accept NaN values...
r496
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564 // Values
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 for (auto valueIndex = 1; valueIndex < expectedNbValues; ++valueIndex) {
auto column = valueIndex;
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564
bool valueOk;
auto value = lineData.at(column).toDouble(&valueOk);
if (!valueOk) {
qCWarning(LOG_AmdaResultParser())
<< QObject::tr(
"Value from (line %1, column %2) is invalid and will be "
"converted to NaN")
.arg(line, column);
value = std::numeric_limits<double>::quiet_NaN();
}
Alexandre Leroux
Uses std::vector when retrieving Amda results
r733 valuesData.push_back(value);
Alexandre Leroux
Updates AMDA result parser to accept NaN values...
r496 }
Alexandre Leroux
Improves AMDA result parsing...
r492 }
else {
qCWarning(LOG_AmdaResultParser())
Alexandre Leroux
Updates AMDA result parser to accept NaN values...
r496 << QObject::tr("Can't retrieve results from line %1: x is invalid")
Alexandre Leroux
Improves AMDA result parsing...
r492 .arg(line);
}
Alexandre Leroux
Improves controls when reading results
r394 }
else {
qCWarning(LOG_AmdaResultParser())
Alexandre Leroux
Improves AMDA result parsing...
r492 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
Alexandre Leroux
Improves controls when reading results
r394 }
Alexandre Leroux
- Changes the way to retrieve unit in AMDA result file: The generated header in the result file differs from the first version...
r774 } while (stream.readLineInto(&line));
Alexandre Leroux
Improves controls when reading results
r394 }
Alexandre Leroux
Uses std::vector when retrieving Amda results
r733 return std::make_pair(std::move(xData), std::move(valuesData));
Alexandre Leroux
Improves controls when reading results
r394 }
Alexandre Leroux
Amda provider (3)...
r380 } // namespace
Alexandre Leroux
Creates enum that represents the value types that can be read in AMDA...
r563 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
ValueType valueType) noexcept
Alexandre Leroux
Amda provider (3)...
r380 {
Alexandre Leroux
Creates enum that represents the value types that can be read in AMDA...
r563 if (valueType == ValueType::UNKNOWN) {
qCCritical(LOG_AmdaResultParser())
<< QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
return nullptr;
}
Alexandre Leroux
Amda provider (3)...
r380 QFile file{filePath};
if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
qCCritical(LOG_AmdaResultParser())
<< QObject::tr("Can't retrieve AMDA data from file %1: %2")
.arg(filePath, file.errorString());
return nullptr;
}
QTextStream stream{&file};
Alexandre Leroux
Handles "Not found" error for AMDA result parser
r446 // Checks if the file was found on the server
auto firstLine = stream.readLine();
if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
qCCritical(LOG_AmdaResultParser())
<< QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
.arg(filePath);
return nullptr;
}
Alexandre Leroux
Reads x-axis unit in result file
r393 // Reads x-axis unit
Alexandre Leroux
Improves AMDA result parsing...
r492 stream.seek(0); // returns to the beginning of the file
Alexandre Leroux
Reads x-axis unit in result file
r393 auto xAxisUnit = readXAxisUnit(stream);
Run request canceling when unit isn"t found in the file. Clean log.
r832 if (xAxisUnit.m_Name.isEmpty()) {
return nullptr;
}
Alexandre Leroux
Reads x-axis unit in result file
r393
// Reads results
Alexandre Leroux
Changes way to retrieve unit
r792 // AMDA V2: remove line
stream.seek(0); // returns to the beginning of the file
Alexandre Leroux
Updates method for reading results according to the value type (vector or scalar)
r564 auto results = readResults(stream, valueType);
Alexandre Leroux
Updates data series creation according to the value type (vector or scalar)
r565 // Creates data series
switch (valueType) {
case ValueType::SCALAR:
Alexandre Leroux
Uses std::vector when retrieving Amda results
r733 return std::make_shared<ScalarSeries>(std::move(results.first),
std::move(results.second), xAxisUnit, Unit{});
case ValueType::VECTOR:
return std::make_shared<VectorSeries>(std::move(results.first),
std::move(results.second), xAxisUnit, Unit{});
Alexandre Leroux
Updates data series creation according to the value type (vector or scalar)
r565 case ValueType::UNKNOWN:
// Invalid case
break;
}
Alexandre Leroux
Amda provider (3)...
r380
Alexandre Leroux
Updates data series creation according to the value type (vector or scalar)
r565 // Invalid cases
qCCritical(LOG_AmdaResultParser())
<< QObject::tr("Can't create data series: unsupported value type");
return nullptr;
Alexandre Leroux
Amda provider (3)...
r380 }