mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1977 Curve Calculator : Trigger parsing and evaluation of expression
This commit is contained in:
@@ -18,8 +18,16 @@
|
||||
|
||||
#include "RimCalculation.h"
|
||||
|
||||
#include "expressionparser/ExpressionParser.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RimCalculationVariable.h"
|
||||
|
||||
#include "cafPdmUiTextEditor.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimCalculation, "RimCalculation");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -29,11 +37,32 @@ RimCalculation::RimCalculation()
|
||||
{
|
||||
CAF_PDM_InitObject("RimCalculation", ":/octave.png", "Calculation", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_expression, "Expression", "Expression", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_variables, "Variables", "Variables", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_description, "Description", "Description", "", "", "");
|
||||
m_description.uiCapability()->setUiReadOnly(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_expression, "Expression", "Expression", "", "", "");
|
||||
m_expression.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_variables, "Variables", "Variables", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_calculatedValues, "CalculatedValues", "Calculated Values", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCalculation::setDescription(const QString& description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCalculation::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -74,7 +103,143 @@ const std::vector<double>& RimCalculation::values() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCalculation::setCalculatedValues(const std::vector<double>& values)
|
||||
caf::PdmFieldHandle* RimCalculation::userDescriptionField()
|
||||
{
|
||||
m_calculatedValues = values;
|
||||
return &m_description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCalculation::parseExpression()
|
||||
{
|
||||
QString leftHandSideVariableName = RimCalculation::findLeftHandSide(m_expression);
|
||||
if (leftHandSideVariableName.isEmpty()) return false;
|
||||
|
||||
std::vector<QString> variableNames = ExpressionParser::detectReferencedVariables(m_expression);
|
||||
|
||||
// Remove variables not present in expression
|
||||
{
|
||||
std::vector<RimCalculationVariable*> toBeDeleted;
|
||||
for (RimCalculationVariable* v : m_variables)
|
||||
{
|
||||
if (std::find(variableNames.begin(), variableNames.end(), v->name()) == variableNames.end())
|
||||
{
|
||||
toBeDeleted.push_back(v);
|
||||
}
|
||||
|
||||
if (leftHandSideVariableName == v->name())
|
||||
{
|
||||
toBeDeleted.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
for (RimCalculationVariable* v : toBeDeleted)
|
||||
{
|
||||
deleteVariable(v);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto variableName : variableNames)
|
||||
{
|
||||
if (leftHandSideVariableName != variableName)
|
||||
{
|
||||
if (!findByName(variableName))
|
||||
{
|
||||
auto v = this->addVariable();
|
||||
v->setName(variableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCalculation::calculate()
|
||||
{
|
||||
if (!parseExpression()) return false;
|
||||
|
||||
QString leftHandSideVariableName = RimCalculation::findLeftHandSide(m_expression);
|
||||
|
||||
ExpressionParser parser;
|
||||
|
||||
std::vector<double> a(10);
|
||||
std::iota(a.begin(), a.end(), 0);
|
||||
|
||||
size_t itemCount = 0;
|
||||
|
||||
for (RimCalculationVariable* v : m_variables)
|
||||
{
|
||||
itemCount = a.size();
|
||||
parser.assignVector(v->name(), a);
|
||||
}
|
||||
|
||||
if (itemCount == 0)
|
||||
{
|
||||
RiaLogging::error("Not able to evaluate expression with no data.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_calculatedValues.v().resize(itemCount);
|
||||
parser.assignVector(leftHandSideVariableName, m_calculatedValues.v());
|
||||
|
||||
QString errorText;
|
||||
bool evaluatedOk = parser.evaluate(m_expression, &errorText);
|
||||
|
||||
if (evaluatedOk)
|
||||
{
|
||||
QString txt;
|
||||
for (auto v : m_calculatedValues())
|
||||
{
|
||||
txt += QString::number(v);
|
||||
txt += " ";
|
||||
}
|
||||
|
||||
RiaLogging::info(txt);
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error(errorText);
|
||||
}
|
||||
|
||||
return evaluatedOk;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Find the last assignment using := and interpret the text before the := as LHS
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCalculation::findLeftHandSide(const QString& expresion)
|
||||
{
|
||||
QString exprWithSpace = expresion;
|
||||
exprWithSpace.replace("\n", " ");
|
||||
|
||||
QStringList words = exprWithSpace.split(" ", QString::SkipEmptyParts);
|
||||
|
||||
int index = words.lastIndexOf(":=");
|
||||
if (index > 0)
|
||||
{
|
||||
return words[index - 1];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCalculationVariable* RimCalculation::findByName(const QString& name) const
|
||||
{
|
||||
for (RimCalculationVariable* v : m_variables)
|
||||
{
|
||||
if (v->name() == name)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimNamedObject.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
class RimCalculationVariable;
|
||||
|
||||
@@ -28,21 +28,33 @@ class RimCalculationVariable;
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCalculation : public RimNamedObject
|
||||
class RimCalculation : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCalculation();
|
||||
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
|
||||
caf::PdmChildArrayFieldHandle* variables();
|
||||
RimCalculationVariable* addVariable();
|
||||
void deleteVariable(RimCalculationVariable* calcVariable);
|
||||
|
||||
const std::vector<double>& values() const;
|
||||
void setCalculatedValues(const std::vector<double>& values);
|
||||
|
||||
bool parseExpression();
|
||||
bool calculate();
|
||||
|
||||
virtual caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
private:
|
||||
static QString findLeftHandSide(const QString& expresion);
|
||||
RimCalculationVariable* findByName(const QString& name) const;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_description;
|
||||
caf::PdmField<QString> m_expression;
|
||||
caf::PdmChildArrayField<RimCalculationVariable*> m_variables;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ RimCalculationCollection::RimCalculationCollection()
|
||||
RimCalculation* RimCalculationCollection::addCalculation()
|
||||
{
|
||||
RimCalculation* calculation = new RimCalculation;
|
||||
calculation->setName(QString("Calculation %1").arg(m_calcuations.size()));
|
||||
calculation->setDescription(QString("Calculation %1").arg(m_calcuations.size()));
|
||||
|
||||
m_calcuations.push_back(calculation);
|
||||
|
||||
|
||||
@@ -54,6 +54,22 @@ RimCalculationVariable::RimCalculationVariable()
|
||||
m_summaryAddress = new RimSummaryAddress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCalculationVariable::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCalculationVariable::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -40,7 +40,8 @@ class RimCalculationVariable : public caf::PdmObject
|
||||
public:
|
||||
RimCalculationVariable();
|
||||
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString& name);
|
||||
|
||||
private:
|
||||
QString summaryAddressDisplayString() const;
|
||||
|
||||
Reference in New Issue
Block a user