mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4580 Import Eclipse RFT data as part of ensemble import
This commit is contained in:
@@ -1,52 +1,69 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaRftPltCurveDefinition.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaRftPltCurveDefinition::RiaRftPltCurveDefinition(RifDataSourceForRftPlt address, const QDateTime timeStep)
|
||||
RiaRftPltCurveDefinition::RiaRftPltCurveDefinition(const RifDataSourceForRftPlt& address, const QString& wellName, const QDateTime& timeStep)
|
||||
: m_curveAddress(address)
|
||||
, m_wellName(wellName)
|
||||
, m_timeStep(timeStep)
|
||||
{
|
||||
m_curveDefinition = std::make_pair(address, timeStep);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt RiaRftPltCurveDefinition::address() const
|
||||
const RifDataSourceForRftPlt& RiaRftPltCurveDefinition::address() const
|
||||
{
|
||||
return m_curveDefinition.first;
|
||||
return m_curveAddress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QDateTime RiaRftPltCurveDefinition::timeStep() const
|
||||
const QString& RiaRftPltCurveDefinition::wellName() const
|
||||
{
|
||||
return m_curveDefinition.second;
|
||||
return m_wellName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QDateTime& RiaRftPltCurveDefinition::timeStep() const
|
||||
{
|
||||
return m_timeStep;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaRftPltCurveDefinition::operator<(const RiaRftPltCurveDefinition& other) const
|
||||
{
|
||||
return m_curveDefinition < other.m_curveDefinition;
|
||||
if (m_curveAddress == other.m_curveAddress)
|
||||
{
|
||||
if (m_wellName == other.m_wellName)
|
||||
{
|
||||
return m_timeStep < other.m_timeStep;
|
||||
}
|
||||
return m_wellName < other.m_wellName;
|
||||
}
|
||||
return m_curveAddress < other.m_curveAddress;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,16 @@ class RimSummaryCase;
|
||||
class RiaRftPltCurveDefinition
|
||||
{
|
||||
public:
|
||||
explicit RiaRftPltCurveDefinition(RifDataSourceForRftPlt address, const QDateTime timeStep);
|
||||
explicit RiaRftPltCurveDefinition(const RifDataSourceForRftPlt& address, const QString& wellName, const QDateTime& timeStep);
|
||||
|
||||
RifDataSourceForRftPlt address() const;
|
||||
QDateTime timeStep() const;
|
||||
const RifDataSourceForRftPlt& address() const;
|
||||
const QString& wellName() const;
|
||||
const QDateTime& timeStep() const;
|
||||
|
||||
bool operator < (const RiaRftPltCurveDefinition& other) const;
|
||||
|
||||
private:
|
||||
std::pair<RifDataSourceForRftPlt, QDateTime> m_curveDefinition;
|
||||
RifDataSourceForRftPlt m_curveAddress;
|
||||
QString m_wellName;
|
||||
QDateTime m_timeStep;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.inl
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.h
|
||||
@@ -67,7 +68,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.cpp
|
||||
|
||||
@@ -142,6 +142,21 @@ cvf::Color3f RiaColorTools::fromQColorTo3f(QColor color)
|
||||
return cvf::Color3f(color.redF(), color.greenF(), color.blueF());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::blendCvfColors(const cvf::Color3f& color1,
|
||||
const cvf::Color3f& color2,
|
||||
int weight1 /*= 1*/,
|
||||
int weight2 /*= 1*/)
|
||||
{
|
||||
CVF_ASSERT(weight1 > 0 && weight2 > 0);
|
||||
int weightsum = weight1 + weight2;
|
||||
return cvf::Color3f((color1.r() * weight1 + color2.r() * weight2) / weightsum,
|
||||
(color1.g() * weight1 + color2.g() * weight2) / weightsum,
|
||||
(color1.b() * weight1 + color2.b() * weight2) / weightsum);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
static QColor toQColor(cvf::Color4f color);
|
||||
static cvf::Color3f fromQColorTo3f(QColor);
|
||||
|
||||
static QColor blendQColors(const QColor& color1, const QColor& color2, int weight1 = 1, int weight2 = 1);
|
||||
static cvf::Color3f blendCvfColors(const cvf::Color3f& color1, const cvf::Color3f& color2, int weight1 = 1, int weight2 = 1);
|
||||
static QColor blendQColors(const QColor& color1, const QColor& color2, int weight1 = 1, int weight2 = 1);
|
||||
|
||||
private:
|
||||
static float relativeLuminance(cvf::Color3f backgroundColor);
|
||||
|
||||
20
ApplicationCode/Application/Tools/RiaCurveMerger.cpp
Normal file
20
ApplicationCode/Application/Tools/RiaCurveMerger.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "RiaCurveMerger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
bool XValueComparator<double>::equals(const double& lhs, const double& rhs)
|
||||
{
|
||||
double eps = 1.0e-12 * std::max(std::fabs(lhs), std::fabs(rhs));
|
||||
return std::fabs(lhs - rhs) < eps;
|
||||
}
|
||||
|
||||
template<>
|
||||
double XValueComparator<time_t>::diff(const time_t& lhs, const time_t& rhs)
|
||||
{
|
||||
return difftime(lhs, rhs);
|
||||
}
|
||||
87
ApplicationCode/Application/Tools/RiaCurveMerger.h
Normal file
87
ApplicationCode/Application/Tools/RiaCurveMerger.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaCurveDataTools.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
template<typename XValueType>
|
||||
class XValueComparator
|
||||
{
|
||||
public:
|
||||
bool operator()(const XValueType& lhs, const XValueType& rhs) const;
|
||||
static bool equals(const XValueType& lhs, const XValueType& rhs);
|
||||
static double diff(const XValueType& lhs, const XValueType& rhs);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
template<typename XValueType>
|
||||
class RiaCurveMerger
|
||||
{
|
||||
public:
|
||||
typedef XValueComparator<XValueType> XComparator;
|
||||
RiaCurveMerger();
|
||||
|
||||
|
||||
void addCurveData(const std::vector<XValueType>& xValues, const std::vector<double>& yValues);
|
||||
size_t curveCount() const;
|
||||
|
||||
void computeInterpolatedValues(bool includeValuesFromPartialCurves = true);
|
||||
|
||||
RiaCurveDataTools::CurveIntervals validIntervalsForAllXValues() const;
|
||||
const std::vector<XValueType>& allXValues() const;
|
||||
const std::vector<double>& interpolatedYValuesForAllXValues(size_t curveIdx) const;
|
||||
|
||||
// Non-const access is not required by any clients, but the expression parser has no available const interface
|
||||
// for specifying a data source for an expression variable. Allow non-const access to avoid copy of the contained
|
||||
// values, interpolated for all time steps
|
||||
//
|
||||
// See ExpressionParserImpl::assignVector()
|
||||
std::vector<double>& interpolatedYValuesForAllXValues(size_t curveIdx);
|
||||
|
||||
public:
|
||||
// Helper methods, available as public to be able to access from unit tests
|
||||
|
||||
static double interpolatedYValue(const XValueType& xValue,
|
||||
const std::vector<XValueType>& curveXValues,
|
||||
const std::vector<double>& curveYValues);
|
||||
|
||||
private:
|
||||
void computeUnionOfXValues(bool includeValuesFromPartialCurves);
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::vector<XValueType>, std::vector<double>>> m_originalValues;
|
||||
|
||||
RiaCurveDataTools::CurveIntervals m_validIntervalsForAllXValues;
|
||||
|
||||
std::vector<XValueType> m_allXValues;
|
||||
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
|
||||
};
|
||||
|
||||
typedef RiaCurveMerger<time_t> RiaTimeHistoryCurveMerger;
|
||||
|
||||
template<>
|
||||
bool XValueComparator<double>::equals(const double& lhs, const double& rhs);
|
||||
template<>
|
||||
double XValueComparator<time_t>::diff(const time_t& lhs, const time_t& rhs);
|
||||
|
||||
#include "RiaCurveMerger.inl"
|
||||
286
ApplicationCode/Application/Tools/RiaCurveMerger.inl
Normal file
286
ApplicationCode/Application/Tools/RiaCurveMerger.inl
Normal file
@@ -0,0 +1,286 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
bool XValueComparator<XValueType>::operator()(const XValueType& lhs, const XValueType& rhs) const
|
||||
{
|
||||
if (XValueComparator<XValueType>::equals(lhs, rhs))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return lhs < rhs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
double XValueComparator<XValueType>::diff(const XValueType& lhs, const XValueType& rhs)
|
||||
{
|
||||
return lhs - rhs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
bool XValueComparator<XValueType>::equals(const XValueType& lhs, const XValueType& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
RiaCurveMerger<XValueType>::RiaCurveMerger()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::addCurveData(const std::vector<XValueType>& xValues, const std::vector<double>& yValues)
|
||||
{
|
||||
CVF_ASSERT(xValues.size() == yValues.size());
|
||||
|
||||
m_originalValues.push_back(std::make_pair(xValues, yValues));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
size_t RiaCurveMerger<XValueType>::curveCount() const
|
||||
{
|
||||
return m_interpolatedValuesForAllCurves.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
RiaCurveDataTools::CurveIntervals RiaCurveMerger<XValueType>::validIntervalsForAllXValues() const
|
||||
{
|
||||
return m_validIntervalsForAllXValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
const std::vector<XValueType>& RiaCurveMerger<XValueType>::allXValues() const
|
||||
{
|
||||
return m_allXValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
const std::vector<double>& RiaCurveMerger<XValueType>::interpolatedYValuesForAllXValues(size_t curveIdx) const
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
std::vector<double>& RiaCurveMerger<XValueType>::interpolatedYValuesForAllXValues(size_t curveIdx)
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::computeInterpolatedValues(bool includeValuesFromPartialCurves)
|
||||
{
|
||||
m_validIntervalsForAllXValues.clear();
|
||||
m_allXValues.clear();
|
||||
m_interpolatedValuesForAllCurves.clear();
|
||||
|
||||
computeUnionOfXValues(includeValuesFromPartialCurves);
|
||||
|
||||
const size_t curveCount = m_originalValues.size();
|
||||
if (curveCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t dataValueCount = m_allXValues.size();
|
||||
if (dataValueCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_interpolatedValuesForAllCurves.resize(curveCount);
|
||||
|
||||
std::vector<double> accumulatedValidValues(dataValueCount, 1.0);
|
||||
|
||||
for (size_t curveIdx = 0; curveIdx < curveCount; curveIdx++)
|
||||
{
|
||||
std::vector<double>& curveValues = m_interpolatedValuesForAllCurves[curveIdx];
|
||||
curveValues.resize(dataValueCount);
|
||||
|
||||
for (size_t valueIndex = 0; valueIndex < dataValueCount; valueIndex++)
|
||||
{
|
||||
double interpolValue = interpolatedYValue(m_allXValues[valueIndex], m_originalValues[curveIdx].first, m_originalValues[curveIdx].second);
|
||||
if (!RiaCurveDataTools::isValidValue(interpolValue, false))
|
||||
{
|
||||
accumulatedValidValues[valueIndex] = HUGE_VAL;
|
||||
}
|
||||
|
||||
curveValues[valueIndex] = interpolValue;
|
||||
}
|
||||
}
|
||||
|
||||
m_validIntervalsForAllXValues = RiaCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::computeUnionOfXValues(bool includeValuesForPartialCurves)
|
||||
{
|
||||
m_allXValues.clear();
|
||||
|
||||
std::set<XValueType, XComparator> unionOfXValues;
|
||||
|
||||
for (const auto& curveData : m_originalValues)
|
||||
{
|
||||
for (const auto& x : curveData.first)
|
||||
{
|
||||
unionOfXValues.insert(x);
|
||||
}
|
||||
}
|
||||
|
||||
if (!includeValuesForPartialCurves)
|
||||
{
|
||||
for (auto it = unionOfXValues.begin(); it != unionOfXValues.end();)
|
||||
{
|
||||
bool outsideBounds = false;
|
||||
for (const auto& curveData : m_originalValues)
|
||||
{
|
||||
if (curveData.first.empty()) continue;
|
||||
|
||||
if (*it < curveData.first.front() || *it > curveData.first.back())
|
||||
{
|
||||
outsideBounds = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outsideBounds)
|
||||
{
|
||||
it = unionOfXValues.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_allXValues = std::vector<XValueType>(unionOfXValues.begin(), unionOfXValues.end());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
double RiaCurveMerger<XValueType>::interpolatedYValue(const XValueType& interpolationXValue,
|
||||
const std::vector<XValueType>& xValues,
|
||||
const std::vector<double>& yValues)
|
||||
{
|
||||
if (yValues.size() != xValues.size()) return HUGE_VAL;
|
||||
|
||||
const bool removeInterpolatedValues = false;
|
||||
|
||||
for (size_t firstI = 0; firstI < xValues.size(); firstI++)
|
||||
{
|
||||
if (XComparator::equals(xValues.at(firstI), interpolationXValue))
|
||||
{
|
||||
const double& firstValue = yValues.at(firstI);
|
||||
if (!RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return firstValue;
|
||||
}
|
||||
|
||||
size_t secondI = firstI + 1;
|
||||
|
||||
if (secondI < xValues.size())
|
||||
{
|
||||
if (XComparator::equals(xValues.at(secondI), interpolationXValue))
|
||||
{
|
||||
const double& secondValue = yValues.at(secondI);
|
||||
if (!RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
if (xValues.at(firstI) < interpolationXValue && xValues.at(secondI) > interpolationXValue)
|
||||
{
|
||||
const double& firstValue = yValues.at(firstI);
|
||||
const double& secondValue = yValues.at(secondI);
|
||||
|
||||
bool isFirstValid = RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
|
||||
if (!isFirstValid) return HUGE_VAL;
|
||||
|
||||
bool isSecondValid = RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
|
||||
if (!isSecondValid) return HUGE_VAL;
|
||||
|
||||
double firstDiff = fabs(XComparator::diff(interpolationXValue, xValues.at(firstI)));
|
||||
double secondDiff = fabs(XComparator::diff(xValues.at(secondI), interpolationXValue));
|
||||
|
||||
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
||||
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
||||
|
||||
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
||||
|
||||
CVF_ASSERT(RiaCurveDataTools::isValidValue(val, removeInterpolatedValues));
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
|
||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaTimeHistoryCurveMerger::RiaTimeHistoryCurveMerger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::addCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
|
||||
{
|
||||
CVF_ASSERT(values.size() == timeSteps.size());
|
||||
|
||||
m_originalValues.push_back(std::make_pair(values, timeSteps));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaCurveDataTools::CurveIntervals RiaTimeHistoryCurveMerger::validIntervalsForAllTimeSteps() const
|
||||
{
|
||||
return m_validIntervalsForAllTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<time_t>& RiaTimeHistoryCurveMerger::allTimeSteps() const
|
||||
{
|
||||
return m_allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx)
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::computeInterpolatedValues()
|
||||
{
|
||||
m_validIntervalsForAllTimeSteps.clear();
|
||||
m_allTimeSteps.clear();
|
||||
m_interpolatedValuesForAllCurves.clear();
|
||||
|
||||
computeUnionOfTimeSteps();
|
||||
|
||||
const size_t curveCount = m_originalValues.size();
|
||||
if (curveCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t dataValueCount = m_allTimeSteps.size();
|
||||
if (dataValueCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_interpolatedValuesForAllCurves.resize(curveCount);
|
||||
|
||||
std::vector<double> accumulatedValidValues(dataValueCount, 1.0);
|
||||
|
||||
for (size_t curveIdx = 0; curveIdx < curveCount; curveIdx++)
|
||||
{
|
||||
std::vector<double>& curveValues = m_interpolatedValuesForAllCurves[curveIdx];
|
||||
curveValues.resize(dataValueCount);
|
||||
|
||||
for (size_t valueIndex = 0; valueIndex < dataValueCount; valueIndex++)
|
||||
{
|
||||
double interpolValue = interpolationValue(m_allTimeSteps[valueIndex], m_originalValues[curveIdx].first, m_originalValues[curveIdx].second);
|
||||
if (!RiaCurveDataTools::isValidValue(interpolValue, false))
|
||||
{
|
||||
accumulatedValidValues[valueIndex] = HUGE_VAL;
|
||||
}
|
||||
|
||||
curveValues[valueIndex] = interpolValue;
|
||||
}
|
||||
}
|
||||
|
||||
m_validIntervalsForAllTimeSteps = RiaCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::computeUnionOfTimeSteps()
|
||||
{
|
||||
m_allTimeSteps.clear();
|
||||
|
||||
std::set<time_t> unionOfTimeSteps;
|
||||
|
||||
for (const auto& curveData : m_originalValues)
|
||||
{
|
||||
for (const auto& dt : curveData.second)
|
||||
{
|
||||
unionOfTimeSteps.insert(dt);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& dt : unionOfTimeSteps)
|
||||
{
|
||||
m_allTimeSteps.push_back(dt);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RiaTimeHistoryCurveMerger::interpolationValue(const time_t& interpolationTimeStep,
|
||||
const std::vector<double>& curveValues,
|
||||
const std::vector<time_t>& curveTimeSteps)
|
||||
{
|
||||
if (curveValues.size() != curveTimeSteps.size()) return HUGE_VAL;
|
||||
|
||||
const bool removeInterpolatedValues = false;
|
||||
|
||||
for (size_t firstI = 0; firstI < curveTimeSteps.size(); firstI++)
|
||||
{
|
||||
if (curveTimeSteps.at(firstI) == interpolationTimeStep)
|
||||
{
|
||||
const double& firstValue = curveValues.at(firstI);
|
||||
if (!RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return firstValue;
|
||||
}
|
||||
|
||||
size_t secondI = firstI + 1;
|
||||
|
||||
if (secondI < curveTimeSteps.size() &&
|
||||
curveTimeSteps.at(firstI) <= interpolationTimeStep &&
|
||||
curveTimeSteps.at(secondI) > interpolationTimeStep)
|
||||
{
|
||||
if (curveTimeSteps.at(secondI) == interpolationTimeStep)
|
||||
{
|
||||
const double& secondValue = curveValues.at(secondI);
|
||||
if (!RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
const double& firstValue = curveValues.at(firstI);
|
||||
const double& secondValue = curveValues.at(secondI);
|
||||
|
||||
bool isFirstValid = RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
|
||||
if (!isFirstValid) return HUGE_VAL;
|
||||
|
||||
bool isSecondValid = RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
|
||||
if (!isSecondValid) return HUGE_VAL;
|
||||
|
||||
double firstDiff = fabs(difftime(interpolationTimeStep, curveTimeSteps.at(firstI)));
|
||||
double secondDiff = fabs(difftime(curveTimeSteps.at(secondI), interpolationTimeStep));
|
||||
|
||||
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
||||
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
||||
|
||||
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
||||
|
||||
CVF_ASSERT(RiaCurveDataTools::isValidValue(val, removeInterpolatedValues));
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaCurveDataTools.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RiaTimeHistoryCurveMerger
|
||||
{
|
||||
public:
|
||||
RiaTimeHistoryCurveMerger();
|
||||
|
||||
|
||||
void addCurveData(const std::vector<double>& values,
|
||||
const std::vector<time_t>& timeSteps);
|
||||
|
||||
void computeInterpolatedValues();
|
||||
|
||||
RiaCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const;
|
||||
const std::vector<time_t>& allTimeSteps() const;
|
||||
const std::vector<double>& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const;
|
||||
|
||||
// Non-const access is not required by any clients, but the expression parser has no available const interface
|
||||
// for specifying a data source for an expression variable. Allow non-const access to avoid copy of the contained
|
||||
// values, interpolated for all time steps
|
||||
//
|
||||
// See ExpressionParserImpl::assignVector()
|
||||
std::vector<double>& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx);
|
||||
|
||||
public:
|
||||
// Helper methods, available as public to be able to access from unit tests
|
||||
|
||||
static double interpolationValue(const time_t& interpolationTimeStep,
|
||||
const std::vector<double>& curveValues,
|
||||
const std::vector<time_t>& curveTimeSteps);
|
||||
|
||||
private:
|
||||
void computeUnionOfTimeSteps();
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::vector<double>, std::vector<time_t>>> m_originalValues;
|
||||
|
||||
RiaCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps;
|
||||
|
||||
std::vector<time_t> m_allTimeSteps;
|
||||
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
|
||||
};
|
||||
@@ -41,6 +41,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportFmuObservedDataFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataInMenuFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportGeneralDataFeature.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportFeatureImpl.h
|
||||
@@ -121,6 +122,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportFmuObservedDataFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataInMenuFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicImportGeneralDataFeature.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExportFeatureImpl.cpp
|
||||
|
||||
@@ -234,7 +234,7 @@ void RicGridStatisticsDialog::createAndConnectToolbarActions()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicGridStatisticsDialog::deletePlotItems(QwtPlot* plot)
|
||||
{
|
||||
auto itemList = plot->itemList();
|
||||
QwtPlotItemList itemList = plot->itemList();
|
||||
for (auto item : itemList)
|
||||
{
|
||||
if (dynamic_cast<QwtPlotMarker*>(item)
|
||||
|
||||
70
ApplicationCode/Commands/RicImportFmuObservedDataFeature.cpp
Normal file
70
ApplicationCode/Commands/RicImportFmuObservedDataFeature.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RicImportFmuObservedDataFeature.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RifReaderFmuRft.h"
|
||||
|
||||
#include "RimObservedData.h"
|
||||
#include "RimObservedDataCollection.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportFmuObservedDataFeature::selectObservedDataPathInDialog()
|
||||
{
|
||||
RiaApplication* app = RiaApplication::instance();
|
||||
QString defaultDir = app->lastUsedDialogDirectory("SUMMARY_CASE_DIR");
|
||||
QString directory = QFileDialog::getExistingDirectory(
|
||||
nullptr, "Import Fmu Observed Data Recursively from Directory", defaultDir, QFileDialog::ShowDirsOnly);
|
||||
|
||||
QStringList subDirsWithFmuData = RifReaderFmuRft::findSubDirectoriesWithFmuRftData(directory);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicImportFmuObservedDataFeature::isCommandEnabled()
|
||||
{
|
||||
std::vector<RimObservedDataCollection*> selectionObservedDataCollection;
|
||||
caf::SelectionManager::instance()->objectsByType(&selectionObservedDataCollection);
|
||||
|
||||
std::vector<RimObservedData*> selectionObservedData;
|
||||
caf::SelectionManager::instance()->objectsByType(&selectionObservedData);
|
||||
|
||||
return (selectionObservedDataCollection.size() > 0 || selectionObservedData.size() > 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportFmuObservedDataFeature::onActionTriggered(bool isChecked) {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicImportFmuObservedDataFeature::setupActionLook(QAction* actionToSetup) {}
|
||||
40
ApplicationCode/Commands/RicImportFmuObservedDataFeature.h
Normal file
40
ApplicationCode/Commands/RicImportFmuObservedDataFeature.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafCmdFeature.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RicImportFmuObservedDataFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
static void selectObservedDataPathInDialog();
|
||||
|
||||
private:
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
};
|
||||
@@ -37,13 +37,6 @@
|
||||
|
||||
CAF_CMD_SOURCE_INIT(RicImportObservedDataFeature, "RicImportObservedDataFeature");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RicImportObservedDataFeature::RicImportObservedDataFeature()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -32,7 +32,6 @@ class RicImportObservedDataFeature : public caf::CmdFeature
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RicImportObservedDataFeature();
|
||||
static void selectObservedDataFileInDialog();
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,7 +16,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifKeywordVectorParser.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderObservedData.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseSummary.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRftInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderFmuRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifJsonEncodeDecode.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderInterface.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderMockModel.h
|
||||
@@ -42,6 +44,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifSummaryCaseRestartSelector.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCaseRealizationParametersReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifFileParseTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEnsembleStatisticsRft.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifActiveCellsReader.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvDataTableFormatter.h
|
||||
@@ -68,7 +71,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RifColumnBasedUserDataParser.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifKeywordVectorParser.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderObservedData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseSummary.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderRftInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEclipseRft.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderFmuRft.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifJsonEncodeDecode.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderInterface.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderMockModel.cpp
|
||||
@@ -95,6 +100,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifActiveCellsReader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifCsvDataTableFormatter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RifReaderEnsembleStatisticsRft.cpp
|
||||
|
||||
# HDF5 file reader is directly included in ResInsight main CmakeList.txt
|
||||
#${CMAKE_CURRENT_LIST_DIR}/RifHdf5Reader.cpp
|
||||
|
||||
@@ -135,6 +135,14 @@ std::string RifColumnBasedUserData::unitName(const RifEclipseSummaryAddress& res
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifColumnBasedUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -48,7 +48,8 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress,
|
||||
std::vector<double>* values) const override;
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
void buildTimeStepsAndMappings();
|
||||
|
||||
@@ -140,6 +140,14 @@ std::string RifCsvUserData::unitName(const RifEclipseSummaryAddress& resultAddre
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifCsvUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
void buildTimeStepsAndMappings();
|
||||
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifDataSourceForRftPlt.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimWellLogFile.h"
|
||||
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "cafAppEnum.h"
|
||||
#include "cvfAssert.h"
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
#include "RimEclipseResultCase.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt() : m_sourceType(SourceType::NONE)
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt()
|
||||
: m_sourceType(SourceType::NONE)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimEclipseCase* eclCase)
|
||||
{
|
||||
@@ -43,22 +45,47 @@ RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimEclipse
|
||||
CVF_ASSERT(eclCase != nullptr);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_eclCase = eclCase;
|
||||
m_eclCase = eclCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimWellLogFile* wellLogFile)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::OBSERVED);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_sourceType = sourceType;
|
||||
m_wellLogFile = wellLogFile;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::ENSEMBLE_RFT);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_ensemble = ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::RifDataSourceForRftPlt(SourceType sourceType,
|
||||
RimSummaryCase* summaryCase,
|
||||
RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
CVF_ASSERT(sourceType == SourceType::SUMMARY_RFT);
|
||||
|
||||
m_sourceType = sourceType;
|
||||
m_summaryCase = summaryCase;
|
||||
m_ensemble = ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt::SourceType RifDataSourceForRftPlt::sourceType() const
|
||||
{
|
||||
@@ -66,7 +93,7 @@ RifDataSourceForRftPlt::SourceType RifDataSourceForRftPlt::sourceType() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RifDataSourceForRftPlt::eclCase() const
|
||||
{
|
||||
@@ -74,22 +101,45 @@ RimEclipseCase* RifDataSourceForRftPlt::eclCase() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRft* RifDataSourceForRftPlt::rftReader() const
|
||||
RifReaderRftInterface* RifDataSourceForRftPlt::rftReader() const
|
||||
{
|
||||
if (m_sourceType == RFT)
|
||||
{
|
||||
auto eclResCase = dynamic_cast<RimEclipseResultCase*>(m_eclCase.p());
|
||||
|
||||
if (eclResCase ) return eclResCase->rftReader();
|
||||
if (eclResCase) return eclResCase->rftReader();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
else if (m_sourceType == SUMMARY_RFT)
|
||||
{
|
||||
if (m_summaryCase) return m_summaryCase->rftReader();
|
||||
}
|
||||
else if (m_sourceType == ENSEMBLE_RFT)
|
||||
{
|
||||
if (m_ensemble) return m_ensemble->rftStatisticsReader();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RifDataSourceForRftPlt::ensemble() const
|
||||
{
|
||||
return m_ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RifDataSourceForRftPlt::summaryCase() const
|
||||
{
|
||||
return m_summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellLogFile* RifDataSourceForRftPlt::wellLogFile() const
|
||||
{
|
||||
@@ -97,33 +147,40 @@ RimWellLogFile* RifDataSourceForRftPlt::wellLogFile() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RifDataSourceForRftPlt::sourceTypeUiText(SourceType sourceType)
|
||||
{
|
||||
switch (sourceType)
|
||||
{
|
||||
case SourceType::RFT: return QString("RFT File Cases");
|
||||
case SourceType::GRID: return QString("Grid Cases");
|
||||
case SourceType::OBSERVED: return QString("Observed Data");
|
||||
case SourceType::RFT:
|
||||
return QString("RFT File Cases");
|
||||
case SourceType::GRID:
|
||||
return QString("Grid Cases");
|
||||
case SourceType::OBSERVED:
|
||||
return QString("Observed Data");
|
||||
case SourceType::ENSEMBLE_RFT:
|
||||
return QString("Ensembles with RFT Data");
|
||||
case SourceType::SUMMARY_RFT:
|
||||
return QString("Summary case with RFT Data");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool operator==(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2)
|
||||
{
|
||||
return addr1.sourceType() == addr2.sourceType()
|
||||
&& addr1.eclCase() == addr2.eclCase()
|
||||
&& addr1.wellLogFile() == addr2.wellLogFile();
|
||||
return addr1.sourceType() == addr2.sourceType() && addr1.eclCase() == addr2.eclCase() &&
|
||||
addr1.wellLogFile() == addr2.wellLogFile() && addr1.summaryCase() == addr2.summaryCase() &&
|
||||
addr1.ensemble() == addr2.ensemble();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& operator << (QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
QTextStream& operator<<(QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
{
|
||||
// Not implemented
|
||||
CVF_ASSERT(false);
|
||||
@@ -131,9 +188,9 @@ QTextStream& operator << (QTextStream& str, const RifDataSourceForRftPlt& addr)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& operator >> (QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
QTextStream& operator>>(QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
{
|
||||
// Not implemented
|
||||
CVF_ASSERT(false);
|
||||
@@ -146,16 +203,16 @@ QTextStream& operator >> (QTextStream& str, RifDataSourceForRftPlt& source)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2)
|
||||
{
|
||||
if ( addr1.m_sourceType != addr2.m_sourceType )
|
||||
if (addr1.m_sourceType != addr2.m_sourceType)
|
||||
{
|
||||
return addr1.m_sourceType < addr2.m_sourceType;
|
||||
}
|
||||
|
||||
if ( addr1.m_sourceType == RifDataSourceForRftPlt::NONE ) return false; //
|
||||
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::OBSERVED)
|
||||
{
|
||||
if(addr1.wellLogFile() && addr2.wellLogFile())
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::NONE) return false; //
|
||||
|
||||
if (addr1.m_sourceType == RifDataSourceForRftPlt::OBSERVED)
|
||||
{
|
||||
if (addr1.wellLogFile() && addr2.wellLogFile())
|
||||
{
|
||||
return addr1.wellLogFile()->fileName() < addr2.wellLogFile()->fileName();
|
||||
}
|
||||
@@ -164,9 +221,31 @@ bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt
|
||||
return addr1.wellLogFile() < addr2.wellLogFile();
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (addr1.m_sourceType == RifDataSourceForRftPlt::SUMMARY_RFT)
|
||||
{
|
||||
if ( addr1.eclCase() && addr2.eclCase() )
|
||||
if (addr1.summaryCase() && addr2.summaryCase())
|
||||
{
|
||||
return addr1.summaryCase()->caseName() < addr2.summaryCase()->caseName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return addr1.summaryCase() < addr2.summaryCase();
|
||||
}
|
||||
}
|
||||
else if (addr1.m_sourceType == RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
if (addr1.ensemble() && addr2.ensemble())
|
||||
{
|
||||
return addr1.ensemble()->name() < addr2.ensemble()->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
return addr1.ensemble() < addr2.ensemble();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr1.eclCase() && addr2.eclCase())
|
||||
{
|
||||
return addr1.eclCase()->caseId() < addr2.eclCase()->caseId();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
|
||||
class RimWellLogFile;
|
||||
class RimEclipseCase;
|
||||
class RifReaderEclipseRft;
|
||||
class RifReaderRftInterface;
|
||||
class RimSummaryCase;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@@ -46,16 +48,22 @@ public:
|
||||
NONE,
|
||||
OBSERVED,
|
||||
RFT,
|
||||
GRID
|
||||
GRID,
|
||||
ENSEMBLE_RFT,
|
||||
SUMMARY_RFT
|
||||
};
|
||||
|
||||
RifDataSourceForRftPlt();
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimEclipseCase* eclCase);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCaseCollection* ensemble);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimSummaryCase* summaryCase, RimSummaryCaseCollection* ensemble);
|
||||
RifDataSourceForRftPlt(SourceType sourceType, RimWellLogFile* wellLogFile = nullptr);
|
||||
|
||||
SourceType sourceType() const;
|
||||
RimEclipseCase* eclCase() const;
|
||||
RifReaderEclipseRft* rftReader() const;
|
||||
RifReaderRftInterface* rftReader() const;
|
||||
RimSummaryCaseCollection* ensemble() const;
|
||||
RimSummaryCase* summaryCase() const;
|
||||
RimWellLogFile* wellLogFile() const;
|
||||
|
||||
static QString sourceTypeUiText(SourceType sourceType);
|
||||
@@ -64,9 +72,11 @@ public:
|
||||
friend bool operator<(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2);
|
||||
|
||||
private:
|
||||
SourceType m_sourceType;
|
||||
caf::PdmPointer<RimEclipseCase> m_eclCase;
|
||||
caf::PdmPointer<RimWellLogFile> m_wellLogFile;
|
||||
SourceType m_sourceType;
|
||||
caf::PdmPointer<RimEclipseCase> m_eclCase;
|
||||
caf::PdmPointer<RimSummaryCase> m_summaryCase;
|
||||
caf::PdmPointer<RimSummaryCaseCollection> m_ensemble;
|
||||
caf::PdmPointer<RimWellLogFile> m_wellLogFile;
|
||||
};
|
||||
|
||||
bool operator==(const RifDataSourceForRftPlt& addr1, const RifDataSourceForRftPlt& addr2);
|
||||
|
||||
@@ -82,3 +82,11 @@ std::string RifDerivedEnsembleReader::unitName(const RifEclipseSummaryAddress& r
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifDerivedEnsembleReader::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
const std::vector<time_t>& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
RimDerivedEnsembleCase* m_derivedCase;
|
||||
|
||||
@@ -36,14 +36,19 @@ public:
|
||||
enum RftWellLogChannelType
|
||||
{
|
||||
NONE,
|
||||
DEPTH,
|
||||
TVD,
|
||||
PRESSURE,
|
||||
SWAT,
|
||||
SOIL,
|
||||
SGAS,
|
||||
WRAT,
|
||||
ORAT,
|
||||
GRAT
|
||||
GRAT,
|
||||
MD,
|
||||
PRESSURE_P10,
|
||||
PRESSURE_P50,
|
||||
PRESSURE_P90,
|
||||
PRESSURE_MEAN
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@@ -83,6 +83,14 @@ std::string RifEnsembleStatisticsReader::unitName(const RifEclipseSummaryAddress
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifEnsembleStatisticsReader::unitSystem() const
|
||||
{
|
||||
return m_ensembleStatCase->unitSystem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -37,6 +37,9 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
bool validateAddress(const RifEclipseSummaryAddress& address) const;
|
||||
|
||||
|
||||
@@ -231,6 +231,14 @@ std::string RifKeywordVectorUserData::unitName(const RifEclipseSummaryAddress& r
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifKeywordVectorUserData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress,
|
||||
std::vector<double>* values) const override;
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
static bool isTimeHeader(const std::map<QString, QString>& header);
|
||||
|
||||
@@ -81,39 +81,39 @@ void RifReaderEclipseRft::open()
|
||||
timeStep.setTime_t(timeStepTime_t);
|
||||
|
||||
RifEclipseRftAddress addressPressure(wellName, timeStep, RifEclipseRftAddress::PRESSURE);
|
||||
m_eclipseRftAddresses.push_back(addressPressure);
|
||||
m_eclipseRftAddresses.insert(addressPressure);
|
||||
m_rftAddressToLibeclNodeIdx[addressPressure] = i;
|
||||
|
||||
RifEclipseRftAddress addressDepth(wellName, timeStep, RifEclipseRftAddress::DEPTH);
|
||||
m_eclipseRftAddresses.push_back(addressDepth);
|
||||
RifEclipseRftAddress addressDepth(wellName, timeStep, RifEclipseRftAddress::TVD);
|
||||
m_eclipseRftAddresses.insert(addressDepth);
|
||||
m_rftAddressToLibeclNodeIdx[addressDepth] = i;
|
||||
|
||||
if (ecl_rft_node_is_RFT(node))
|
||||
{
|
||||
RifEclipseRftAddress addressSwat(wellName, timeStep, RifEclipseRftAddress::SWAT);
|
||||
m_eclipseRftAddresses.push_back(addressSwat);
|
||||
m_eclipseRftAddresses.insert(addressSwat);
|
||||
m_rftAddressToLibeclNodeIdx[addressSwat] = i;
|
||||
|
||||
RifEclipseRftAddress addressSoil(wellName, timeStep, RifEclipseRftAddress::SOIL);
|
||||
m_eclipseRftAddresses.push_back(addressSoil);
|
||||
m_eclipseRftAddresses.insert(addressSoil);
|
||||
m_rftAddressToLibeclNodeIdx[addressSoil] = i;
|
||||
|
||||
RifEclipseRftAddress addressSgas(wellName, timeStep, RifEclipseRftAddress::SGAS);
|
||||
m_eclipseRftAddresses.push_back(addressSgas);
|
||||
m_eclipseRftAddresses.insert(addressSgas);
|
||||
m_rftAddressToLibeclNodeIdx[addressSgas] = i;
|
||||
}
|
||||
else if (ecl_rft_node_is_PLT(node))
|
||||
{
|
||||
RifEclipseRftAddress addressWrat(wellName, timeStep, RifEclipseRftAddress::WRAT);
|
||||
m_eclipseRftAddresses.push_back(addressWrat);
|
||||
m_eclipseRftAddresses.insert(addressWrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressWrat] = i;
|
||||
|
||||
RifEclipseRftAddress addressOrat(wellName, timeStep, RifEclipseRftAddress::ORAT);
|
||||
m_eclipseRftAddresses.push_back(addressOrat);
|
||||
m_eclipseRftAddresses.insert(addressOrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressOrat] = i;
|
||||
|
||||
RifEclipseRftAddress addressGrat(wellName, timeStep, RifEclipseRftAddress::GRAT);
|
||||
m_eclipseRftAddresses.push_back(addressGrat);
|
||||
m_eclipseRftAddresses.insert(addressGrat);
|
||||
m_rftAddressToLibeclNodeIdx[addressGrat] = i;
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ void RifReaderEclipseRft::open()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<RifEclipseRftAddress>& RifReaderEclipseRft::eclipseRftAddresses()
|
||||
std::set<RifEclipseRftAddress> RifReaderEclipseRft::eclipseRftAddresses()
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ void RifReaderEclipseRft::values(const RifEclipseRftAddress& rftAddress, std::ve
|
||||
|
||||
switch (wellLogChannelName)
|
||||
{
|
||||
case RifEclipseRftAddress::DEPTH:
|
||||
case RifEclipseRftAddress::TVD:
|
||||
{
|
||||
for (int i = 0; i < ecl_rft_node_get_size(node); i++)
|
||||
{
|
||||
@@ -258,14 +258,14 @@ void RifReaderEclipseRft::cellIndices(const RifEclipseRftAddress& rftAddress, st
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
std::vector<QDateTime> timeSteps;
|
||||
std::set<QDateTime> timeSteps;
|
||||
|
||||
if (wellName == "") return timeSteps;
|
||||
|
||||
@@ -273,7 +273,7 @@ std::vector<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& we
|
||||
{
|
||||
if (address.wellName() == wellName && address.wellLogChannel() == wellLogChannelName)
|
||||
{
|
||||
timeSteps.push_back(address.timeStep());
|
||||
timeSteps.insert(address.timeStep());
|
||||
}
|
||||
}
|
||||
return timeSteps;
|
||||
@@ -303,17 +303,26 @@ std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellN
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEclipseRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
auto wellLogChannels = availableWellLogChannels(wellName);
|
||||
return availableTimeSteps(wellName, wellLogChannels);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::availableWellLogChannels(const QString& wellName)
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannelNames;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannelNames;
|
||||
|
||||
if (wellName == "") return wellLogChannelNames;
|
||||
|
||||
@@ -359,19 +368,19 @@ std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::av
|
||||
|
||||
if (pressureFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::PRESSURE);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::PRESSURE);
|
||||
}
|
||||
if (rftFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SWAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SOIL);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::SGAS);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SWAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SOIL);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::SGAS);
|
||||
}
|
||||
if (pltFound)
|
||||
{
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::WRAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::ORAT);
|
||||
wellLogChannelNames.push_back(RifEclipseRftAddress::RftWellLogChannelType::GRAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::WRAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::ORAT);
|
||||
wellLogChannelNames.insert(RifEclipseRftAddress::RftWellLogChannelType::GRAT);
|
||||
}
|
||||
|
||||
return wellLogChannelNames;
|
||||
@@ -380,7 +389,7 @@ std::vector<RifEclipseRftAddress::RftWellLogChannelType> RifReaderEclipseRft::av
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::set<QString>& RifReaderEclipseRft::wellNames()
|
||||
std::set<QString> RifReaderEclipseRft::wellNames()
|
||||
{
|
||||
if (!m_ecl_rft_file)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseRftAddress.h"
|
||||
#include "RifReaderRftInterface.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -38,26 +38,27 @@ namespace caf
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderEclipseRft : public cvf::Object
|
||||
class RifReaderEclipseRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEclipseRft(const QString& fileName);
|
||||
~RifReaderEclipseRft() override;
|
||||
|
||||
const std::vector<RifEclipseRftAddress>& eclipseRftAddresses();
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values);
|
||||
void cellIndices(const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices);
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
void cellIndices(const RifEclipseRftAddress& rftAddress, std::vector<caf::VecIjk>* indices);
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels);
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
|
||||
std::vector<QDateTime> availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName);
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName);
|
||||
const std::set<QString>& wellNames();
|
||||
bool wellHasRftData(QString wellName);
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName, const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
bool wellHasRftData(QString wellName);
|
||||
|
||||
private:
|
||||
void open();
|
||||
int indexFromAddress(const RifEclipseRftAddress& rftAddress) const;
|
||||
void open();
|
||||
int indexFromAddress(const RifEclipseRftAddress& rftAddress) const;
|
||||
|
||||
private:
|
||||
// Taken from ecl_rft_file.h and ecl_rft_node.h
|
||||
@@ -65,7 +66,7 @@ private:
|
||||
|
||||
QString m_fileName;
|
||||
ecl_rft_file_type* m_ecl_rft_file;
|
||||
std::vector<RifEclipseRftAddress> m_eclipseRftAddresses;
|
||||
std::set<RifEclipseRftAddress> m_eclipseRftAddresses;
|
||||
std::set<QString> m_wellNames;
|
||||
std::map<RifEclipseRftAddress, int> m_rftAddressToLibeclNodeIdx;
|
||||
};
|
||||
|
||||
@@ -57,6 +57,22 @@ std::vector<time_t> getTimeSteps(ecl_sum_type* ecl_sum)
|
||||
return timeSteps;
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem readUnitSystem(ecl_sum_type* ecl_sum)
|
||||
{
|
||||
ert_ecl_unit_enum eclUnitEnum = ecl_sum_get_unit_system(ecl_sum);
|
||||
switch (eclUnitEnum)
|
||||
{
|
||||
case ECL_METRIC_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_METRIC;
|
||||
case ECL_FIELD_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_FIELD;
|
||||
case ECL_LAB_UNITS:
|
||||
return RiaEclipseUnitTools::UNITS_LAB;
|
||||
default:
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -105,6 +121,7 @@ void closeEclSum(ecl_sum_type* ecl_sum)
|
||||
RifReaderEclipseSummary::RifReaderEclipseSummary()
|
||||
: m_ecl_sum(nullptr)
|
||||
, m_ecl_SmSpec(nullptr)
|
||||
, m_unitSystem(RiaEclipseUnitTools::UNITS_METRIC)
|
||||
{
|
||||
m_valuesCache.reset(new ValuesCache());
|
||||
}
|
||||
@@ -135,7 +152,7 @@ bool RifReaderEclipseSummary::open(const QString& headerFileName, bool includeRe
|
||||
m_timeSteps.clear();
|
||||
m_ecl_SmSpec = ecl_sum_get_smspec(m_ecl_sum);
|
||||
m_timeSteps = getTimeSteps(m_ecl_sum);
|
||||
|
||||
m_unitSystem = readUnitSystem(m_ecl_sum);
|
||||
buildMetaData();
|
||||
|
||||
return true;
|
||||
@@ -515,6 +532,14 @@ std::string RifReaderEclipseSummary::unitName(const RifEclipseSummaryAddress& re
|
||||
return ertSumVarNode.get_unit();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifReaderEclipseSummary::unitSystem() const
|
||||
{
|
||||
return m_unitSystem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
|
||||
bool values(const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values) const override;
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
QStringList warnings() const { return m_warnings; }
|
||||
|
||||
void markForCachePurge(const RifEclipseSummaryAddress& address) override;
|
||||
@@ -88,6 +89,8 @@ private:
|
||||
const ecl_smspec_type * m_ecl_SmSpec;
|
||||
std::vector<time_t> m_timeSteps;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem m_unitSystem;
|
||||
|
||||
std::map<RifEclipseSummaryAddress, int> m_resultAddressToErtNodeIdx;
|
||||
|
||||
QStringList m_warnings;
|
||||
|
||||
258
ApplicationCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp
Normal file
258
ApplicationCode/FileInterface/RifReaderEnsembleStatisticsRft.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RifReaderEnsembleStatisticsRft.h"
|
||||
|
||||
#include "RiaCurveMerger.h"
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEnsembleStatisticsRft::RifReaderEnsembleStatisticsRft(const RimSummaryCaseCollection* summaryCaseCollection)
|
||||
: m_summaryCaseCollection(summaryCaseCollection)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderEnsembleStatisticsRft::eclipseRftAddresses()
|
||||
{
|
||||
std::set<RifEclipseRftAddress> allAddresses;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<RifEclipseRftAddress> addresses = summaryCase->rftReader()->eclipseRftAddresses();
|
||||
allAddresses.insert(addresses.begin(), addresses.end());
|
||||
}
|
||||
}
|
||||
|
||||
std::set<RifEclipseRftAddress> statisticsAddresses;
|
||||
for (const RifEclipseRftAddress& regularAddress : allAddresses)
|
||||
{
|
||||
if (regularAddress.wellLogChannel() == RifEclipseRftAddress::TVD)
|
||||
{
|
||||
statisticsAddresses.insert(regularAddress);
|
||||
}
|
||||
else if (regularAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE)
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> statChannels = {RifEclipseRftAddress::PRESSURE_P10,
|
||||
RifEclipseRftAddress::PRESSURE_P50,
|
||||
RifEclipseRftAddress::PRESSURE_P90,
|
||||
RifEclipseRftAddress::PRESSURE_MEAN};
|
||||
for (auto channel : statChannels)
|
||||
{
|
||||
statisticsAddresses.insert(RifEclipseRftAddress(regularAddress.wellName(), regularAddress.timeStep(), channel));
|
||||
}
|
||||
}
|
||||
}
|
||||
return statisticsAddresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values)
|
||||
{
|
||||
CAF_ASSERT(rftAddress.wellLogChannel() == RifEclipseRftAddress::TVD ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_MEAN ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P10 ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P50 ||
|
||||
rftAddress.wellLogChannel() == RifEclipseRftAddress::PRESSURE_P90);
|
||||
|
||||
auto it = m_cachedValues.find(rftAddress);
|
||||
if (it == m_cachedValues.end())
|
||||
{
|
||||
calculateStatistics(rftAddress);
|
||||
}
|
||||
*values = m_cachedValues[rftAddress];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEnsembleStatisticsRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime>
|
||||
RifReaderEnsembleStatisticsRft::availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName, wellLogChannelName);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderEnsembleStatisticsRft::availableTimeSteps(
|
||||
const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels)
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(wellName, relevantChannels);
|
||||
allTimeSteps.insert(timeSteps.begin(), timeSteps.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType>
|
||||
RifReaderEnsembleStatisticsRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> allWellLogChannels;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> wellLogChannels =
|
||||
summaryCase->rftReader()->availableWellLogChannels(wellName);
|
||||
allWellLogChannels.insert(wellLogChannels.begin(), wellLogChannels.end());
|
||||
}
|
||||
}
|
||||
return allWellLogChannels;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RifReaderEnsembleStatisticsRft::wellNames()
|
||||
{
|
||||
std::set<QString> allWellNames;
|
||||
for (auto summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
if (summaryCase->rftReader())
|
||||
{
|
||||
std::set<QString> wellNames = summaryCase->rftReader()->wellNames();
|
||||
allWellNames.insert(wellNames.begin(), wellNames.end());
|
||||
}
|
||||
}
|
||||
return allWellNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::calculateStatistics(const RifEclipseRftAddress& rftAddress)
|
||||
{
|
||||
const QString& wellName = rftAddress.wellName();
|
||||
const QDateTime& timeStep = rftAddress.timeStep();
|
||||
RifEclipseRftAddress depthAddress(wellName, timeStep, RifEclipseRftAddress::TVD);
|
||||
RifEclipseRftAddress pressAddress(wellName, timeStep, RifEclipseRftAddress::PRESSURE);
|
||||
|
||||
RifEclipseRftAddress p10Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P10);
|
||||
RifEclipseRftAddress p50Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P50);
|
||||
RifEclipseRftAddress p90Address(wellName, timeStep, RifEclipseRftAddress::PRESSURE_P90);
|
||||
RifEclipseRftAddress meanAddress(wellName, timeStep, RifEclipseRftAddress::PRESSURE_MEAN);
|
||||
|
||||
RiaCurveMerger<double> curveMerger;
|
||||
|
||||
for (RimSummaryCase* summaryCase : m_summaryCaseCollection->allSummaryCases())
|
||||
{
|
||||
RifReaderRftInterface* reader = summaryCase->rftReader();
|
||||
if (reader)
|
||||
{
|
||||
std::vector<double> depths;
|
||||
std::vector<double> pressures;
|
||||
reader->values(depthAddress, &depths);
|
||||
reader->values(pressAddress, &pressures);
|
||||
|
||||
curveMerger.addCurveData(depths, pressures);
|
||||
}
|
||||
}
|
||||
curveMerger.computeInterpolatedValues(false);
|
||||
|
||||
clearData(wellName, timeStep);
|
||||
|
||||
const std::vector<double>& allDepths = curveMerger.allXValues();
|
||||
if (!allDepths.empty())
|
||||
{
|
||||
m_cachedValues[depthAddress] = allDepths;
|
||||
for (size_t depthIdx = 0; depthIdx < allDepths.size(); ++depthIdx)
|
||||
{
|
||||
std::vector<double> pressuresAtDepth;
|
||||
pressuresAtDepth.reserve(curveMerger.curveCount());
|
||||
for (size_t curveIdx = 0; curveIdx < curveMerger.curveCount(); ++curveIdx)
|
||||
{
|
||||
const std::vector<double>& curvePressures = curveMerger.interpolatedYValuesForAllXValues(curveIdx);
|
||||
pressuresAtDepth.push_back(curvePressures[depthIdx]);
|
||||
}
|
||||
double p10, p50, p90, mean;
|
||||
RigStatisticsMath::calculateStatisticsCurves(pressuresAtDepth, &p10, &p50, &p90, &mean);
|
||||
|
||||
if (p10 != HUGE_VAL) m_cachedValues[p10Address].push_back(p10);
|
||||
if (p50 != HUGE_VAL) m_cachedValues[p50Address].push_back(p50);
|
||||
if (p90 != HUGE_VAL) m_cachedValues[p90Address].push_back(p90);
|
||||
m_cachedValues[meanAddress].push_back(mean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderEnsembleStatisticsRft::clearData(const QString& wellName, const QDateTime& timeStep)
|
||||
{
|
||||
for (auto it = m_cachedValues.begin(); it != m_cachedValues.end(); )
|
||||
{
|
||||
if (it->first.wellName() == wellName && it->first.timeStep() == timeStep)
|
||||
{
|
||||
it = m_cachedValues.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifReaderEclipseRft.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
class RifReaderEnsembleStatisticsRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
RifReaderEnsembleStatisticsRft(const RimSummaryCaseCollection* summaryCaseCollection);
|
||||
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
|
||||
private:
|
||||
void calculateStatistics(const RifEclipseRftAddress& rftAddress);
|
||||
void clearData(const QString& wellName, const QDateTime& timeStep);
|
||||
private:
|
||||
|
||||
const RimSummaryCaseCollection* m_summaryCaseCollection;
|
||||
|
||||
std::map<RifEclipseRftAddress, std::vector<double>> m_cachedValues;
|
||||
};
|
||||
506
ApplicationCode/FileInterface/RifReaderFmuRft.cpp
Normal file
506
ApplicationCode/FileInterface/RifReaderFmuRft.cpp
Normal file
@@ -0,0 +1,506 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RifReaderFmuRft.h"
|
||||
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::Observation::Observation()
|
||||
: utmx(-std::numeric_limits<double>::infinity())
|
||||
, utmy(-std::numeric_limits<double>::infinity())
|
||||
, mdrkb(-std::numeric_limits<double>::infinity())
|
||||
, tvdmsl(-std::numeric_limits<double>::infinity())
|
||||
, pressure(-std::numeric_limits<double>::infinity())
|
||||
, pressureError(-std::numeric_limits<double>::infinity())
|
||||
, formation()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::Observation::valid() const
|
||||
{
|
||||
return utmx != std::numeric_limits<double>::infinity() && utmy != std::numeric_limits<double>::infinity() &&
|
||||
mdrkb != std::numeric_limits<double>::infinity() && tvdmsl != std::numeric_limits<double>::infinity() &&
|
||||
pressure != std::numeric_limits<double>::infinity() && pressureError != std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::WellObservationSet::WellObservationSet(const QDateTime& dateTime, int measurementIndex)
|
||||
: dateTime(dateTime)
|
||||
, measurementIndex(measurementIndex)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::RifReaderFmuRft(const QString& filePath)
|
||||
: m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList RifReaderFmuRft::findSubDirectoriesWithFmuRftData(const QString& filePath)
|
||||
{
|
||||
QStringList subDirsContainingFmuRftData;
|
||||
|
||||
QFileInfo fileInfo(filePath);
|
||||
if (!(fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable()))
|
||||
{
|
||||
return subDirsContainingFmuRftData;
|
||||
}
|
||||
|
||||
if (directoryContainsFmuRftData(filePath))
|
||||
{
|
||||
subDirsContainingFmuRftData.push_back(filePath);
|
||||
}
|
||||
|
||||
QDir dir(filePath);
|
||||
|
||||
QStringList subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable, QDir::Name);
|
||||
for (QString subDir : subDirs)
|
||||
{
|
||||
QString absDir = dir.absoluteFilePath(subDir);
|
||||
subDirsContainingFmuRftData.append(findSubDirectoriesWithFmuRftData(absDir));
|
||||
}
|
||||
|
||||
return subDirsContainingFmuRftData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::directoryContainsFmuRftData(const QString& filePath)
|
||||
{
|
||||
QFileInfo baseFileInfo(filePath);
|
||||
if (!(baseFileInfo.exists() && baseFileInfo.isDir() && baseFileInfo.isReadable()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir dir(filePath);
|
||||
if (!dir.exists("well_date_rft.txt"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList obsFiles;
|
||||
obsFiles << "*.obs"
|
||||
<< "*.txt";
|
||||
QFileInfoList fileInfos = dir.entryInfoList(obsFiles, QDir::Files, QDir::Name);
|
||||
|
||||
std::map<QString, int> fileStemCounts;
|
||||
for (QFileInfo fileInfo : fileInfos)
|
||||
{
|
||||
// TODO:
|
||||
// Uses completeBaseName() to support wells with a dot in the name.
|
||||
// Not sure if this is necessary or desired
|
||||
fileStemCounts[fileInfo.completeBaseName()]++;
|
||||
if (fileStemCounts[fileInfo.completeBaseName()] == 2)
|
||||
{
|
||||
// At least one matching obs and txt file.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderFmuRft::eclipseRftAddresses()
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
std::set<RifEclipseRftAddress> allAddresses;
|
||||
for (const WellObservationPair& wellObservationPair : m_allWellObservations)
|
||||
{
|
||||
const QString& wellName = wellObservationPair.first;
|
||||
const QDateTime& dateTime = wellObservationPair.second.dateTime;
|
||||
const std::vector<Observation>& observations = wellObservationPair.second.observations;
|
||||
|
||||
for (const Observation& observation : observations)
|
||||
{
|
||||
if (observation.valid())
|
||||
{
|
||||
RifEclipseRftAddress tvdAddress(wellName, dateTime, RifEclipseRftAddress::TVD);
|
||||
RifEclipseRftAddress mdAddress(wellName, dateTime, RifEclipseRftAddress::MD);
|
||||
RifEclipseRftAddress pressureAddress(wellName, dateTime, RifEclipseRftAddress::PRESSURE);
|
||||
allAddresses.insert(tvdAddress);
|
||||
allAddresses.insert(mdAddress);
|
||||
allAddresses.insert(pressureAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
return allAddresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderFmuRft::values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values)
|
||||
{
|
||||
CAF_ASSERT(values);
|
||||
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
auto it = m_allWellObservations.find(rftAddress.wellName());
|
||||
if (it != m_allWellObservations.end())
|
||||
{
|
||||
const std::vector<Observation>& observations = it->second.observations;
|
||||
values->clear();
|
||||
values->reserve(observations.size());
|
||||
for (const Observation& observation : observations)
|
||||
{
|
||||
switch (rftAddress.wellLogChannel())
|
||||
{
|
||||
case RifEclipseRftAddress::TVD:
|
||||
values->push_back(observation.tvdmsl);
|
||||
break;
|
||||
case RifEclipseRftAddress::MD:
|
||||
values->push_back(observation.mdrkb);
|
||||
break;
|
||||
case RifEclipseRftAddress::PRESSURE:
|
||||
values->push_back(observation.pressure);
|
||||
break;
|
||||
default:
|
||||
CAF_ASSERT(false && "Wrong channel type sent to Fmu RFT reader");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RifReaderFmuRft::load()
|
||||
{
|
||||
QString errorMsg;
|
||||
|
||||
QFileInfo fileInfo(m_filePath);
|
||||
if (!(fileInfo.exists() && fileInfo.isDir() && fileInfo.isReadable()))
|
||||
{
|
||||
errorMsg = QString("Directory '%s' does not exist or isn't readable").arg(m_filePath);
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
QDir dir(m_filePath);
|
||||
|
||||
WellObservationMap wellObservations = loadWellDates(dir, &errorMsg);
|
||||
if (wellObservations.empty())
|
||||
{
|
||||
if (errorMsg.isEmpty())
|
||||
{
|
||||
errorMsg = QString("'%1' contains no valid FMU RFT data").arg(m_filePath);
|
||||
}
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = wellObservations.begin(); it != wellObservations.end(); ++it)
|
||||
{
|
||||
const QString& wellName = it->first;
|
||||
WellObservationSet& wellObservationSet = it->second;
|
||||
QString txtFile = QString("%1.txt").arg(wellName);
|
||||
QString obsFile = QString("%1.obs").arg(wellName);
|
||||
QFileInfo txtFileInfo(dir.absoluteFilePath(txtFile));
|
||||
QFileInfo obsFileInfo(dir.absoluteFilePath(obsFile));
|
||||
|
||||
if (!readTxtFile(txtFile, &errorMsg, &wellObservationSet))
|
||||
{
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!readObsFile(obsFile, &errorMsg, &wellObservationSet))
|
||||
{
|
||||
RiaLogging::error(errorMsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_allWellObservations.swap(wellObservations);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName)
|
||||
{
|
||||
if (wellLogChannelName == RifEclipseRftAddress::TVD || wellLogChannelName == RifEclipseRftAddress::MD ||
|
||||
wellLogChannelName == RifEclipseRftAddress::PRESSURE)
|
||||
{
|
||||
return availableTimeSteps(wellName);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RifReaderFmuRft::availableTimeSteps(const QString& wellName)
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
auto it = m_allWellObservations.find(wellName);
|
||||
if (it != m_allWellObservations.end())
|
||||
{
|
||||
return {it->second.dateTime};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime>
|
||||
RifReaderFmuRft::availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels)
|
||||
{
|
||||
if (relevantChannels.count(RifEclipseRftAddress::TVD) || relevantChannels.count(RifEclipseRftAddress::MD) ||
|
||||
relevantChannels.count(RifEclipseRftAddress::PRESSURE))
|
||||
{
|
||||
return availableTimeSteps(wellName);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderFmuRft::availableWellLogChannels(const QString& wellName)
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
if (!m_allWellObservations.empty())
|
||||
{
|
||||
return {RifEclipseRftAddress::TVD, RifEclipseRftAddress::MD, RifEclipseRftAddress::PRESSURE};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RifReaderFmuRft::wellNames()
|
||||
{
|
||||
if (m_allWellObservations.empty())
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
std::set<QString> wellNames;
|
||||
for (auto it = m_allWellObservations.begin(); it != m_allWellObservations.end(); ++it)
|
||||
{
|
||||
wellNames.insert(it->first);
|
||||
}
|
||||
return wellNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderFmuRft::WellObservationMap RifReaderFmuRft::loadWellDates(QDir& dir, QString* errorMsg)
|
||||
{
|
||||
CAF_ASSERT(errorMsg);
|
||||
|
||||
WellObservationMap validObservations;
|
||||
|
||||
QFileInfo wellDateFileInfo(dir.absoluteFilePath("well_date_rft.txt"));
|
||||
if (!(wellDateFileInfo.exists() && wellDateFileInfo.isFile() && wellDateFileInfo.isReadable()))
|
||||
{
|
||||
*errorMsg = QString("well_date_rft.txt cannot be found at '%s'").arg(m_filePath);
|
||||
return WellObservationMap();
|
||||
}
|
||||
|
||||
{
|
||||
QFile wellDateFile(wellDateFileInfo.absoluteFilePath());
|
||||
if (!wellDateFile.open(QIODevice::Text | QIODevice::ReadOnly))
|
||||
{
|
||||
*errorMsg = QString("Could not read '%1'").arg(wellDateFileInfo.absoluteFilePath());
|
||||
return WellObservationMap();
|
||||
}
|
||||
QTextStream fileStream(&wellDateFile);
|
||||
while (true)
|
||||
{
|
||||
QString line = fileStream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
QString wellName;
|
||||
int day, month, year, measurementIndex;
|
||||
|
||||
lineStream >> wellName >> day >> month >> year >> measurementIndex;
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse '%1'").arg(wellDateFileInfo.absoluteFilePath());
|
||||
return WellObservationMap();
|
||||
}
|
||||
|
||||
QDateTime dateTime(QDate(year, month, day));
|
||||
WellObservationSet observationSet(dateTime, measurementIndex);
|
||||
validObservations.insert(std::make_pair(wellName, observationSet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validObservations;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::readTxtFile(const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet)
|
||||
{
|
||||
CAF_ASSERT(wellObservationSet);
|
||||
|
||||
QFile file(fileName);
|
||||
if (!(file.open(QIODevice::Text | QIODevice::ReadOnly)))
|
||||
{
|
||||
*errorMsg = QString("Could not open '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
while (true)
|
||||
{
|
||||
QString line = stream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
double utmx, utmy, mdrkb, tvdmsl;
|
||||
QString formationName;
|
||||
|
||||
lineStream >> utmx >> utmy >> mdrkb >> tvdmsl >> formationName;
|
||||
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Observation observation;
|
||||
observation.utmx = utmx;
|
||||
observation.utmy = utmy;
|
||||
observation.mdrkb = mdrkb;
|
||||
observation.tvdmsl = tvdmsl;
|
||||
observation.formation = formationName;
|
||||
wellObservationSet->observations.push_back(observation);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifReaderFmuRft::readObsFile(const QString& fileName, QString* errorMsg, WellObservationSet* wellObservationSet)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!(file.open(QIODevice::Text | QIODevice::ReadOnly)))
|
||||
{
|
||||
*errorMsg = QString("Could not open '%1'").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t lineNumber = 0u;
|
||||
|
||||
QTextStream stream(&file);
|
||||
while (true)
|
||||
{
|
||||
if (lineNumber >= wellObservationSet->observations.size())
|
||||
{
|
||||
*errorMsg = QString("'%1' has more lines than corresponding txt file").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
QString line = stream.readLine();
|
||||
if (line.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextStream lineStream(&line);
|
||||
|
||||
double pressure, pressureError;
|
||||
|
||||
lineStream >> pressure >> pressureError;
|
||||
|
||||
if (lineStream.status() != QTextStream::Ok)
|
||||
{
|
||||
*errorMsg = QString("Failed to parse line %1 of '%2'").arg(lineNumber + 1).arg(fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Observation& observation = wellObservationSet->observations[lineNumber];
|
||||
observation.pressure = pressure;
|
||||
observation.pressureError = pressureError;
|
||||
}
|
||||
lineNumber++;
|
||||
}
|
||||
|
||||
if (lineNumber != wellObservationSet->observations.size())
|
||||
{
|
||||
*errorMsg = QString("'%1' has less lines than corresponding txt file").arg(fileName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
98
ApplicationCode/FileInterface/RifReaderFmuRft.h
Normal file
98
ApplicationCode/FileInterface/RifReaderFmuRft.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseRftAddress.h"
|
||||
#include "RifReaderRftInterface.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cvfBase.h"
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class RifReaderFmuRft : public RifReaderRftInterface, public cvf::Object
|
||||
{
|
||||
public:
|
||||
struct Observation
|
||||
{
|
||||
double utmx;
|
||||
double utmy;
|
||||
double mdrkb;
|
||||
double tvdmsl;
|
||||
|
||||
double pressure;
|
||||
double pressureError;
|
||||
QString formation;
|
||||
|
||||
Observation();
|
||||
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
struct WellObservationSet
|
||||
{
|
||||
QDateTime dateTime;
|
||||
int measurementIndex;
|
||||
std::vector<Observation> observations;
|
||||
|
||||
WellObservationSet(const QDateTime& dateTime, int measurementIndex);
|
||||
};
|
||||
|
||||
public:
|
||||
RifReaderFmuRft(const QString& filePath);
|
||||
~RifReaderFmuRft() = default;
|
||||
|
||||
static QStringList findSubDirectoriesWithFmuRftData(const QString& filePath);
|
||||
static bool directoryContainsFmuRftData(const QString& filePath);
|
||||
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses() override;
|
||||
void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) override;
|
||||
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName) override;
|
||||
std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) override;
|
||||
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) override;
|
||||
std::set<QString> wellNames() override;
|
||||
|
||||
public:
|
||||
void load();
|
||||
|
||||
private:
|
||||
typedef std::pair<QString, WellObservationSet> WellObservationPair;
|
||||
typedef std::map<QString, WellObservationSet> WellObservationMap;
|
||||
|
||||
WellObservationMap loadWellDates(QDir& dir, QString* errorMsg);
|
||||
static bool readTxtFile(const QString& txtFileName, QString* errorMsg, WellObservationSet* wellObservationSet);
|
||||
static bool readObsFile(const QString& obsFileName, QString* errorMsg, WellObservationSet* wellObservationSet);
|
||||
|
||||
private:
|
||||
QString m_filePath;
|
||||
WellObservationMap m_allWellObservations;
|
||||
};
|
||||
@@ -183,3 +183,11 @@ std::string RifReaderObservedData::unitName(const RifEclipseSummaryAddress& resu
|
||||
std::string str = "";
|
||||
return str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifReaderObservedData::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
|
||||
std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
RifEclipseSummaryAddress address(const QString& quantity,
|
||||
const QString& identifierName,
|
||||
|
||||
37
ApplicationCode/FileInterface/RifReaderRftInterface.cpp
Normal file
37
ApplicationCode/FileInterface/RifReaderRftInterface.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RifReaderRftInterface.h"
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseRftAddress> RifReaderRftInterface::eclipseRftAddresses(const QString& wellName, const QDateTime& timeStep)
|
||||
{
|
||||
std::set<RifEclipseRftAddress> matchingAddresses;
|
||||
std::set<RifEclipseRftAddress> allAddresses = this->eclipseRftAddresses();
|
||||
for (const RifEclipseRftAddress& address : allAddresses)
|
||||
{
|
||||
if (address.wellName() == wellName && address.timeStep() == timeStep)
|
||||
{
|
||||
matchingAddresses.insert(address);
|
||||
}
|
||||
}
|
||||
return matchingAddresses;
|
||||
}
|
||||
44
ApplicationCode/FileInterface/RifReaderRftInterface.h
Normal file
44
ApplicationCode/FileInterface/RifReaderRftInterface.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseRftAddress.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
class RifReaderRftInterface
|
||||
{
|
||||
public:
|
||||
std::set<RifEclipseRftAddress> eclipseRftAddresses(const QString& wellName, const QDateTime& timeStep);
|
||||
virtual std::set<RifEclipseRftAddress> eclipseRftAddresses() = 0;
|
||||
virtual void values(const RifEclipseRftAddress& rftAddress, std::vector<double>* values) = 0;
|
||||
|
||||
virtual std::set<QDateTime>
|
||||
availableTimeSteps(const QString& wellName,
|
||||
const std::set<RifEclipseRftAddress::RftWellLogChannelType> relevantChannels) = 0;
|
||||
virtual std::set<QDateTime> availableTimeSteps(const QString& wellName) = 0;
|
||||
virtual std::set<QDateTime> availableTimeSteps(const QString& wellName,
|
||||
const RifEclipseRftAddress::RftWellLogChannelType& wellLogChannelName) = 0;
|
||||
virtual std::set<RifEclipseRftAddress::RftWellLogChannelType> availableWellLogChannels(const QString& wellName) = 0;
|
||||
virtual std::set<QString> wellNames() = 0;
|
||||
};
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
@@ -50,7 +51,7 @@ public:
|
||||
std::vector<double>* values) const = 0;
|
||||
|
||||
virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) const = 0;
|
||||
|
||||
virtual RiaEclipseUnitTools::UnitSystem unitSystem() const = 0;
|
||||
|
||||
virtual void markForCachePurge(const RifEclipseSummaryAddress& address) {}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace caf
|
||||
addItem(RifDataSourceForRftPlt::SourceType::RFT, "RFT", "RFT Cases");
|
||||
addItem(RifDataSourceForRftPlt::SourceType::GRID, "GRID", "Grid Cases");
|
||||
addItem(RifDataSourceForRftPlt::SourceType::OBSERVED, "OBSERVED", "Observed Data");
|
||||
addItem(RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT, "ENSEMBLE", "Ensembles with RFT Data");
|
||||
setDefault(RifDataSourceForRftPlt::SourceType::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimWellLogExtractionCurve.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellLogFileChannel.h"
|
||||
@@ -406,6 +408,48 @@ std::vector<RimEclipseResultCase*> RimWellPlotTools::rftCasesForWell(const QStri
|
||||
return cases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell(const QString& simWellName)
|
||||
{
|
||||
const RimProject* project = RiaApplication::instance()->project();
|
||||
|
||||
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections = project->summaryGroups();
|
||||
|
||||
std::vector<RimSummaryCaseCollection*> rftEnsembles;
|
||||
|
||||
for (RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections)
|
||||
{
|
||||
if (summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->rftTimeStepsForWell(simWellName).empty())
|
||||
{
|
||||
rftEnsembles.push_back(summaryCaseColl);
|
||||
}
|
||||
}
|
||||
return rftEnsembles;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
|
||||
{
|
||||
const RimProject* project = RiaApplication::instance()->project();
|
||||
|
||||
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections = project->summaryGroups();
|
||||
|
||||
std::vector<RimSummaryCaseCollection*> rftEnsembles;
|
||||
|
||||
for (RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections)
|
||||
{
|
||||
if (summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->wellsWithRftData().empty())
|
||||
{
|
||||
rftEnsembles.push_back(summaryCaseColl);
|
||||
}
|
||||
}
|
||||
return rftEnsembles;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -495,12 +539,28 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
|
||||
|
||||
if (rftCurve != nullptr)
|
||||
{
|
||||
RimEclipseResultCase* rftCase = dynamic_cast<RimEclipseResultCase*>(rftCurve->eclipseResultCase());
|
||||
RimEclipseResultCase* rftCase = dynamic_cast<RimEclipseResultCase*>(rftCurve->eclipseResultCase());
|
||||
RimSummaryCase* rftSummaryCase = rftCurve->summaryCase();
|
||||
RimSummaryCaseCollection* rftEnsemble = rftCurve->ensemble();
|
||||
|
||||
const RifEclipseRftAddress rftAddress = rftCurve->rftAddress();
|
||||
const QString& wellName = rftAddress.wellName();
|
||||
const QDateTime& timeStep = rftAddress.timeStep();
|
||||
|
||||
if (rftCase != nullptr)
|
||||
{
|
||||
const RifEclipseRftAddress rftAddress = rftCurve->rftAddress();
|
||||
const QDateTime timeStep = rftAddress.timeStep();
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::RFT, rftCase), timeStep);
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::RFT, rftCase), wellName, timeStep);
|
||||
}
|
||||
else if (rftSummaryCase != nullptr)
|
||||
{
|
||||
rftSummaryCase->firstAncestorOrThisOfTypeAsserted(rftEnsemble);
|
||||
return RiaRftPltCurveDefinition(
|
||||
RifDataSourceForRftPlt(RifDataSourceForRftPlt::SUMMARY_RFT, rftSummaryCase, rftEnsemble), wellName, timeStep);
|
||||
}
|
||||
else if (rftEnsemble != nullptr)
|
||||
{
|
||||
return RiaRftPltCurveDefinition(
|
||||
RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, rftEnsemble), wellName, timeStep);
|
||||
}
|
||||
}
|
||||
else if (gridCurve != nullptr)
|
||||
@@ -515,6 +575,7 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
|
||||
if (timeStepIndex < timeStepsMap.size())
|
||||
{
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::GRID, gridCase),
|
||||
gridCurve->wellName(),
|
||||
timeStepsVector[timeStepIndex].first);
|
||||
}
|
||||
}
|
||||
@@ -529,11 +590,12 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
|
||||
|
||||
if (date.isValid())
|
||||
{
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, wellLogFile), date);
|
||||
return RiaRftPltCurveDefinition(
|
||||
RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, wellLogFile), wellLogFile->wellName(), date);
|
||||
}
|
||||
}
|
||||
}
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(), QDateTime());
|
||||
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(), QString(), QDateTime());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -591,14 +653,14 @@ std::set<RiaRftPltCurveDefinition>
|
||||
|
||||
for (const RifDataSourceForRftPlt& addr : selectedSourcesExpanded)
|
||||
{
|
||||
if (addr.rftReader())
|
||||
if (addr.sourceType() == RifDataSourceForRftPlt::RFT && addr.rftReader())
|
||||
{
|
||||
std::set<QDateTime> rftTimes = addr.rftReader()->availableTimeSteps(simWellName, interestingRFTResults);
|
||||
for (const QDateTime& time : rftTimes)
|
||||
{
|
||||
if (selectedTimeStepSet.count(time))
|
||||
{
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, time));
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,7 +673,7 @@ std::set<RiaRftPltCurveDefinition>
|
||||
{
|
||||
if (selectedTimeStepSet.count(time))
|
||||
{
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, time));
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,7 +683,37 @@ std::set<RiaRftPltCurveDefinition>
|
||||
{
|
||||
if (selectedTimeStepSet.count(addr.wellLogFile()->date()))
|
||||
{
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, addr.wellLogFile()->date()));
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, addr.wellLogFile()->date()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (addr.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
if (addr.ensemble())
|
||||
{
|
||||
for (RimSummaryCase* summaryCase : addr.ensemble()->allSummaryCases())
|
||||
{
|
||||
if (summaryCase && summaryCase->rftReader())
|
||||
{
|
||||
RifDataSourceForRftPlt summaryAddr(RifDataSourceForRftPlt::SUMMARY_RFT, summaryCase, addr.ensemble());
|
||||
|
||||
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(simWellName);
|
||||
for (const QDateTime& time : timeSteps)
|
||||
{
|
||||
if (selectedTimeStepSet.count(time))
|
||||
{
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(summaryAddr, simWellName, time));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::set<QDateTime> statTimeSteps = addr.ensemble()->rftTimeStepsForWell(simWellName);
|
||||
for (const QDateTime& time : statTimeSteps)
|
||||
{
|
||||
if (selectedTimeStepSet.count(time))
|
||||
{
|
||||
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,9 +872,11 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
{
|
||||
bool addFirstTimestep = (interestingRFTResults.count(RifEclipseRftAddress::PRESSURE) == 1);
|
||||
|
||||
bool hasObservedData = false;
|
||||
bool hasRftData = false;
|
||||
bool hasGridData = false;
|
||||
bool hasObservedData = false;
|
||||
bool hasRftData = false;
|
||||
bool hasGridData = false;
|
||||
bool hasEnsembleData = false;
|
||||
bool hasSummaryRftData = false;
|
||||
|
||||
for (const auto& source : selSources)
|
||||
{
|
||||
@@ -797,12 +891,20 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
case RifDataSourceForRftPlt::OBSERVED:
|
||||
hasObservedData = true;
|
||||
break;
|
||||
case RifDataSourceForRftPlt::SUMMARY_RFT:
|
||||
hasSummaryRftData = true;
|
||||
break;
|
||||
case RifDataSourceForRftPlt::ENSEMBLE_RFT:
|
||||
hasEnsembleData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> observedTimeStepsWithSources;
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> rftTimeStepsWithSources;
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> gridTimestepsWithSources;
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> summaryRftTimeStepsWithSources;
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> ensembleTimeStepsWithSources;
|
||||
|
||||
if (hasObservedData)
|
||||
{
|
||||
@@ -848,6 +950,39 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSummaryRftData)
|
||||
{
|
||||
for (const auto& source : selSources)
|
||||
{
|
||||
if (source.sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT && source.summaryCase())
|
||||
{
|
||||
std::set<QDateTime> wellTimeSteps =
|
||||
source.summaryCase()->rftReader()->availableTimeSteps(wellPathNameOrSimWellName);
|
||||
|
||||
for (const QDateTime& date : wellTimeSteps)
|
||||
{
|
||||
summaryRftTimeStepsWithSources[date].insert(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEnsembleData)
|
||||
{
|
||||
for (const auto& source : selSources)
|
||||
{
|
||||
if (source.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT && source.ensemble())
|
||||
{
|
||||
std::set<QDateTime> wellTimeSteps = source.ensemble()->rftTimeStepsForWell(wellPathNameOrSimWellName);
|
||||
|
||||
for (const QDateTime& date : wellTimeSteps)
|
||||
{
|
||||
ensembleTimeStepsWithSources[date].insert(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a time baseline add the equal or adjacent grid timesteps
|
||||
|
||||
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> timestepsToShowWithSources;
|
||||
@@ -861,6 +996,14 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
{
|
||||
timeBaseline = &rftTimeStepsWithSources;
|
||||
}
|
||||
else if (hasSummaryRftData)
|
||||
{
|
||||
timeBaseline = &summaryRftTimeStepsWithSources;
|
||||
}
|
||||
else if (hasEnsembleData)
|
||||
{
|
||||
timeBaseline = &ensembleTimeStepsWithSources;
|
||||
}
|
||||
|
||||
if (timeBaseline)
|
||||
{
|
||||
@@ -876,9 +1019,21 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
for (const auto& dateSourceSetPair : gridTimestepsWithSources)
|
||||
gridTimeSteps.insert(dateSourceSetPair.first);
|
||||
|
||||
std::set<QDateTime> summaryRftTimeSteps;
|
||||
for (const auto& dateSourceSetPair : summaryRftTimeStepsWithSources)
|
||||
summaryRftTimeSteps.insert(dateSourceSetPair.first);
|
||||
|
||||
std::set<QDateTime> ensembleRftTimeSteps;
|
||||
for (const auto& dateSourceSetPair : ensembleTimeStepsWithSources)
|
||||
ensembleRftTimeSteps.insert(dateSourceSetPair.first);
|
||||
|
||||
std::set<QDateTime> filteredRftTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, rftTimeSteps);
|
||||
std::set<QDateTime> filteredGridTimeSteps =
|
||||
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, gridTimeSteps);
|
||||
std::set<QDateTime> filteredSummaryRftTimeSteps =
|
||||
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, summaryRftTimeSteps);
|
||||
std::set<QDateTime> filteredEnsembleRftTimeSteps =
|
||||
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, ensembleRftTimeSteps);
|
||||
|
||||
if (addFirstTimestep && gridTimeSteps.size())
|
||||
{
|
||||
@@ -889,6 +1044,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
timestepsToShowWithSources = observedTimeStepsWithSources;
|
||||
|
||||
std::set<QDateTime>& allFilteredTimesteps = filteredRftTimeSteps;
|
||||
allFilteredTimesteps.insert(filteredEnsembleRftTimeSteps.begin(), filteredEnsembleRftTimeSteps.end());
|
||||
allFilteredTimesteps.insert(filteredGridTimeSteps.begin(), filteredGridTimeSteps.end());
|
||||
|
||||
for (const QDateTime& time : allFilteredTimesteps)
|
||||
@@ -900,11 +1056,25 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
|
||||
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
||||
}
|
||||
|
||||
auto gridTimeSourceSetIt = gridTimestepsWithSources.find(time);
|
||||
auto gridTimeSourceSetIt = gridTimestepsWithSources.find(time);
|
||||
if (gridTimeSourceSetIt != gridTimestepsWithSources.end())
|
||||
{
|
||||
std::set<RifDataSourceForRftPlt>& sourceSet = gridTimeSourceSetIt->second;
|
||||
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
||||
}
|
||||
|
||||
auto summaryRftTimeSourceSetIt = summaryRftTimeStepsWithSources.find(time);
|
||||
if (summaryRftTimeSourceSetIt != summaryRftTimeStepsWithSources.end())
|
||||
{
|
||||
std::set<RifDataSourceForRftPlt>& sourceSet = summaryRftTimeSourceSetIt->second;
|
||||
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
||||
}
|
||||
|
||||
auto ensembleRftTimeSourceSetIt = ensembleTimeStepsWithSources.find(time);
|
||||
if (ensembleRftTimeSourceSetIt != ensembleTimeStepsWithSources.end())
|
||||
{
|
||||
std::set<RifDataSourceForRftPlt>& sourceSet = ensembleRftTimeSourceSetIt->second;
|
||||
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,9 +1113,10 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps(
|
||||
{
|
||||
QString optionText = RiaQDateTimeTools::toStringUsingApplicationLocale(timeStepPair.first, dateFormatString);
|
||||
|
||||
bool hasObs = false;
|
||||
bool hasRft = false;
|
||||
bool hasGrid = false;
|
||||
bool hasObs = false;
|
||||
bool hasRft = false;
|
||||
bool hasGrid = false;
|
||||
bool hasEnsemble = false;
|
||||
|
||||
for (const auto& source : timeStepPair.second)
|
||||
{
|
||||
@@ -960,15 +1131,19 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps(
|
||||
case RifDataSourceForRftPlt::GRID:
|
||||
hasGrid = true;
|
||||
break;
|
||||
case RifDataSourceForRftPlt::ENSEMBLE_RFT:
|
||||
hasEnsemble = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
optionText += " \t[ ";
|
||||
if (hasObs) optionText += "O ";
|
||||
if (hasRft) optionText += "R ";
|
||||
if (hasGrid) optionText += "G";
|
||||
optionText += " ]";
|
||||
QStringList optionTags;
|
||||
if (hasObs) optionTags << "O";
|
||||
if (hasRft) optionTags << "R";
|
||||
if (hasGrid) optionTags << "G";
|
||||
if (hasEnsemble) optionTags << "E";
|
||||
|
||||
optionText += QString(" \t[%1]").arg(optionTags.join(", "));
|
||||
options.push_back(caf::PdmOptionItemInfo(optionText, timeStepPair.first));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
class RimEclipseCase;
|
||||
class RimEclipseResultCase;
|
||||
class RimSummaryCaseCollection;
|
||||
class RimWellLogCurve;
|
||||
class RimWellLogFileChannel;
|
||||
class RimWellLogPlot;
|
||||
@@ -82,6 +83,8 @@ public:
|
||||
// Both
|
||||
static std::vector<RimEclipseResultCase*> gridCasesForWell(const QString& simWellName);
|
||||
static std::vector<RimEclipseResultCase*> rftCasesForWell(const QString& simWellName);
|
||||
static std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell(const QString& simWellName);
|
||||
static std::vector<RimSummaryCaseCollection*> rftEnsembles();
|
||||
static QString simWellName(const QString& wellPathNameOrSimWellName);
|
||||
|
||||
static std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "RimWellRftPlot.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaDateStringParser.h"
|
||||
#include "RiaSimWellBranchTools.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogExtractionCurve.h"
|
||||
#include "RimWellLogFile.h"
|
||||
@@ -49,6 +51,7 @@
|
||||
#include "RimWellPlotTools.h"
|
||||
#include "RimWellPltPlot.h"
|
||||
|
||||
#include "RiuWellLogTrack.h"
|
||||
#include "RiuWellRftPlot.h"
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
@@ -76,6 +79,8 @@ RimWellRftPlot::RimWellRftPlot()
|
||||
m_userName.uiCapability()->setUiReadOnly(true);
|
||||
|
||||
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
|
||||
CAF_PDM_InitField(&m_showStatisticsCurves, "ShowStatisticsCurves", true, "Show Statistics Curves", "", "", "");
|
||||
CAF_PDM_InitField(&m_showEnsembleCurves, "ShowEnsembleCurves", true, "Show Ensemble Curves", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_wellLogPlot, "WellLog", "Well Log", "", "", "");
|
||||
m_wellLogPlot.uiCapability()->setUiHidden(true);
|
||||
@@ -135,94 +140,39 @@ void RimWellRftPlot::deleteViewWidget()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellRftPlot::applyCurveAppearance(RimWellLogCurve* newCurve)
|
||||
{
|
||||
const RiaRftPltCurveDefinition& newCurveDef = RimWellPlotTools::curveDefFromCurve(newCurve);
|
||||
RiaRftPltCurveDefinition newCurveDef = RimWellPlotTools::curveDefFromCurve(newCurve);
|
||||
|
||||
std::vector<cvf::Color3f> colorTable;
|
||||
RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable);
|
||||
RiuQwtPlotCurve::LineStyleEnum currentLineStyle = RiuQwtPlotCurve::STYLE_SOLID;
|
||||
|
||||
std::vector<RiuQwtSymbol::PointSymbolEnum> symbolTable = {RiuQwtSymbol::SYMBOL_ELLIPSE,
|
||||
RiuQwtSymbol::SYMBOL_RECT,
|
||||
RiuQwtSymbol::SYMBOL_DIAMOND,
|
||||
RiuQwtSymbol::SYMBOL_TRIANGLE,
|
||||
RiuQwtSymbol::SYMBOL_CROSS,
|
||||
RiuQwtSymbol::SYMBOL_XCROSS};
|
||||
|
||||
// State variables
|
||||
static size_t defaultColorTableIndex = 0;
|
||||
static size_t defaultSymbolTableIndex = 0;
|
||||
|
||||
cvf::Color3f currentColor;
|
||||
RiuQwtSymbol::PointSymbolEnum currentSymbol = symbolTable.front();
|
||||
RiuQwtPlotCurve::LineStyleEnum currentLineStyle = RiuQwtPlotCurve::STYLE_SOLID;
|
||||
bool isCurrentColorSet = false;
|
||||
bool isCurrentSymbolSet = false;
|
||||
|
||||
std::set<cvf::Color3f> assignedColors;
|
||||
std::set<RiuQwtSymbol::PointSymbolEnum> assignedSymbols;
|
||||
|
||||
// Used colors and symbols
|
||||
for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector())
|
||||
{
|
||||
if (curve == newCurve) continue;
|
||||
|
||||
RiaRftPltCurveDefinition cDef = RimWellPlotTools::curveDefFromCurve(curve);
|
||||
if (cDef.address() == newCurveDef.address())
|
||||
{
|
||||
currentColor = curve->color();
|
||||
isCurrentColorSet = true;
|
||||
}
|
||||
if (cDef.timeStep() == newCurveDef.timeStep())
|
||||
{
|
||||
currentSymbol = curve->symbol();
|
||||
isCurrentSymbolSet = true;
|
||||
}
|
||||
assignedColors.insert(curve->color());
|
||||
assignedSymbols.insert(curve->symbol());
|
||||
}
|
||||
|
||||
// Assign color
|
||||
if (!isCurrentColorSet)
|
||||
{
|
||||
for (const auto& color : colorTable)
|
||||
{
|
||||
if (assignedColors.count(color) == 0)
|
||||
{
|
||||
currentColor = color;
|
||||
isCurrentColorSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isCurrentColorSet)
|
||||
{
|
||||
currentColor = colorTable[defaultColorTableIndex];
|
||||
if (++defaultColorTableIndex == colorTable.size()) defaultColorTableIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign symbol
|
||||
if (!isCurrentSymbolSet)
|
||||
{
|
||||
for (const auto& symbol : symbolTable)
|
||||
{
|
||||
if (assignedSymbols.count(symbol) == 0)
|
||||
{
|
||||
currentSymbol = symbol;
|
||||
isCurrentSymbolSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isCurrentSymbolSet)
|
||||
{
|
||||
currentSymbol = symbolTable[defaultSymbolTableIndex];
|
||||
if (++defaultSymbolTableIndex == symbolTable.size()) defaultSymbolTableIndex = 0;
|
||||
}
|
||||
}
|
||||
cvf::Color3f currentColor;
|
||||
if (newCurveDef.address().sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT)
|
||||
{
|
||||
RifDataSourceForRftPlt sourceAddress(RifDataSourceForRftPlt::ENSEMBLE_RFT, newCurveDef.address().ensemble());
|
||||
currentColor = m_dataSourceColors[sourceAddress];
|
||||
if (m_showStatisticsCurves)
|
||||
{
|
||||
cvf::Color3f backgroundColor =
|
||||
RiaColorTools::fromQColorTo3f(m_wellLogPlot->trackByIndex(0)->viewer()->canvasBackground().color());
|
||||
currentColor = RiaColorTools::blendCvfColors(backgroundColor, currentColor, 2, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentColor = m_dataSourceColors[newCurveDef.address()];
|
||||
}
|
||||
|
||||
RiuQwtSymbol::PointSymbolEnum currentSymbol = RiuQwtSymbol::SYMBOL_NONE;
|
||||
if (newCurveDef.address().sourceType() != RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
currentSymbol = m_timeStepSymbols[newCurveDef.timeStep()];
|
||||
}
|
||||
|
||||
// Observed data
|
||||
currentLineStyle = newCurveDef.address().sourceType() == RifDataSourceForRftPlt::OBSERVED ? RiuQwtPlotCurve::STYLE_NONE
|
||||
: RiuQwtPlotCurve::STYLE_SOLID;
|
||||
|
||||
newCurve->setColor(currentColor);
|
||||
newCurve->setSymbolEdgeColor(currentColor);
|
||||
newCurve->setSymbol(currentSymbol);
|
||||
newCurve->setLineStyle(currentLineStyle);
|
||||
}
|
||||
@@ -289,6 +239,11 @@ void RimWellRftPlot::applyInitialSelections()
|
||||
sourcesToSelect.push_back(RifDataSourceForRftPlt(RifDataSourceForRftPlt::GRID, gridCase));
|
||||
}
|
||||
|
||||
for (RimSummaryCaseCollection* const ensemble : RimWellPlotTools::rftEnsemblesForWell(simWellName))
|
||||
{
|
||||
sourcesToSelect.push_back(RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, ensemble));
|
||||
}
|
||||
|
||||
std::vector<RimWellLogFile*> wellLogFiles = RimWellPlotTools::wellLogFilesContainingPressure(m_wellPathNameOrSimWellName);
|
||||
if (!wellLogFiles.empty())
|
||||
{
|
||||
@@ -447,6 +402,8 @@ void RimWellRftPlot::updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>
|
||||
// Delete curves
|
||||
plotTrack->deleteAllCurves();
|
||||
|
||||
defineCurveColorsAndSymbols(allCurveDefs);
|
||||
|
||||
// Add new curves
|
||||
for (const RiaRftPltCurveDefinition& curveDefToAdd : allCurveDefs)
|
||||
{
|
||||
@@ -465,6 +422,47 @@ void RimWellRftPlot::updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>
|
||||
|
||||
applyCurveAppearance(curve);
|
||||
}
|
||||
else if (m_showEnsembleCurves && curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT)
|
||||
{
|
||||
auto curve = new RimWellLogRftCurve();
|
||||
plotTrack->addCurve(curve);
|
||||
auto rftCase = curveDefToAdd.address().summaryCase();
|
||||
curve->setSummaryCase(rftCase);
|
||||
RifEclipseRftAddress address(simWellName, curveDefToAdd.timeStep(), RifEclipseRftAddress::PRESSURE);
|
||||
curve->setRftAddress(address);
|
||||
curve->setZOrder(1);
|
||||
applyCurveAppearance(curve);
|
||||
}
|
||||
else if (m_showStatisticsCurves && curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
RimSummaryCaseCollection* ensemble = curveDefToAdd.address().ensemble();
|
||||
std::set<RifEclipseRftAddress> rftAddresses =
|
||||
ensemble->rftStatisticsReader()->eclipseRftAddresses(simWellName, curveDefToAdd.timeStep());
|
||||
for (auto rftAddress : rftAddresses)
|
||||
{
|
||||
if (rftAddress.wellLogChannel() != RifEclipseRftAddress::TVD)
|
||||
{
|
||||
auto curve = new RimWellLogRftCurve();
|
||||
plotTrack->addCurve(curve);
|
||||
curve->setEnsemble(ensemble);
|
||||
curve->setRftAddress(rftAddress);
|
||||
curve->setZOrder(RiuQwtPlotCurve::Z_ENSEMBLE_STAT_CURVE);
|
||||
applyCurveAppearance(curve);
|
||||
auto symbol = statisticsCurveSymbolFromAddress(rftAddress);
|
||||
RiuQwtSymbol::LabelPosition labelPos = statisticsLabelPosFromAddress(rftAddress);
|
||||
curve->setSymbol(symbol);
|
||||
curve->setSymbolLabelPosition(labelPos);
|
||||
curve->setSymbolSize(curve->symbolSize() + 3);
|
||||
curve->setSymbolSkipDistance(150);
|
||||
curve->setLineStyle(RiuQwtPlotCurve::STYLE_SOLID);
|
||||
QString uiText =
|
||||
caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(rftAddress.wellLogChannel());
|
||||
QString label = uiText.replace("Pressure", "");
|
||||
curve->setSymbolLabel(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::GRID)
|
||||
{
|
||||
auto curve = new RimWellLogExtractionCurve();
|
||||
@@ -580,6 +578,14 @@ RimWellLogPlot* RimWellRftPlot::wellLogPlot() const
|
||||
return m_wellLogPlot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QString& RimWellRftPlot::simWellOrWellPathName() const
|
||||
{
|
||||
return m_wellPathNameOrSimWellName.v();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -639,6 +645,21 @@ QList<caf::PdmOptionItemInfo> RimWellRftPlot::calculateValueOptions(const caf::P
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<RimSummaryCaseCollection*> rftEnsembles = RimWellPlotTools::rftEnsemblesForWell(simWellName);
|
||||
if (!rftEnsembles.empty())
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo::createHeader(
|
||||
RifDataSourceForRftPlt::sourceTypeUiText(RifDataSourceForRftPlt::ENSEMBLE_RFT), true));
|
||||
|
||||
for (RimSummaryCaseCollection* rftEnsemble : rftEnsembles)
|
||||
{
|
||||
auto addr = RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, rftEnsemble);
|
||||
auto item = caf::PdmOptionItemInfo(rftEnsemble->name(), QVariant::fromValue(addr));
|
||||
item.setLevel(1);
|
||||
options.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<RimEclipseResultCase*> gridCases = RimWellPlotTools::gridCasesForWell(simWellName);
|
||||
if (!gridCases.empty())
|
||||
{
|
||||
@@ -716,7 +737,14 @@ void RimWellRftPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c
|
||||
{
|
||||
updateFormationsOnPlot();
|
||||
syncCurvesFromUiSelection();
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
else if (changedField == &m_showStatisticsCurves || changedField == &m_showEnsembleCurves)
|
||||
{
|
||||
updateFormationsOnPlot();
|
||||
syncCurvesFromUiSelection();
|
||||
}
|
||||
|
||||
else if (changedField == &m_showPlotTitle)
|
||||
{
|
||||
// m_wellLogPlot->setShowDescription(m_showPlotTitle);
|
||||
@@ -754,6 +782,20 @@ void RimWellRftPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
|
||||
{
|
||||
uiOrdering.add(&m_userName);
|
||||
uiOrdering.add(&m_wellPathNameOrSimWellName);
|
||||
uiOrdering.add(&m_showStatisticsCurves);
|
||||
uiOrdering.add(&m_showEnsembleCurves);
|
||||
|
||||
bool showingEnsembleData = false;
|
||||
for (const RifDataSourceForRftPlt& dataSource : m_selectedSources())
|
||||
{
|
||||
if (dataSource.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
showingEnsembleData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_showStatisticsCurves.uiCapability()->setUiReadOnly(!showingEnsembleData);
|
||||
m_showEnsembleCurves.uiCapability()->setUiReadOnly(!showingEnsembleData);
|
||||
|
||||
RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName(
|
||||
&uiOrdering, m_wellPathNameOrSimWellName, m_branchDetection, m_branchIndex);
|
||||
@@ -818,6 +860,20 @@ void RimWellRftPlot::calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>
|
||||
}
|
||||
}
|
||||
|
||||
// Ensemble RFT wells
|
||||
const std::vector<RimSummaryCaseCollection*> rftEnsembles = RimWellPlotTools::rftEnsembles();
|
||||
if (!rftEnsembles.empty())
|
||||
{
|
||||
for (RimSummaryCaseCollection* summaryCaseColl : rftEnsembles)
|
||||
{
|
||||
std::set<QString> wellsWithRftData = summaryCaseColl->wellsWithRftData();
|
||||
for (QString wellName : wellsWithRftData)
|
||||
{
|
||||
wellNames.insert(std::make_pair(wellName, wellName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& wellName : wellNames)
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(wellName.first, wellName.second));
|
||||
@@ -870,6 +926,8 @@ void RimWellRftPlot::onLoadDataAndUpdate()
|
||||
|
||||
updateEditorsFromCurves();
|
||||
updateWidgetTitleWindowTitle();
|
||||
|
||||
// applyInitialSelections();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -903,3 +961,88 @@ QWidget* RimWellRftPlot::createViewWidget(QWidget* mainWindowParent)
|
||||
|
||||
return m_wellLogPlotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtSymbol::PointSymbolEnum RimWellRftPlot::statisticsCurveSymbolFromAddress(const RifEclipseRftAddress& address)
|
||||
{
|
||||
switch (address.wellLogChannel())
|
||||
{
|
||||
case RifEclipseRftAddress::PRESSURE_P10:
|
||||
return RiuQwtSymbol::SYMBOL_TRIANGLE;
|
||||
case RifEclipseRftAddress::PRESSURE_P50:
|
||||
return RiuQwtSymbol::SYMBOL_DOWN_TRIANGLE;
|
||||
case RifEclipseRftAddress::PRESSURE_P90:
|
||||
return RiuQwtSymbol::SYMBOL_LEFT_TRIANGLE;
|
||||
case RifEclipseRftAddress::PRESSURE_MEAN:
|
||||
return RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE;
|
||||
}
|
||||
return RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtSymbol::LabelPosition RimWellRftPlot::statisticsLabelPosFromAddress(const RifEclipseRftAddress& address)
|
||||
{
|
||||
switch (address.wellLogChannel())
|
||||
{
|
||||
case RifEclipseRftAddress::PRESSURE_P10:
|
||||
return RiuQwtSymbol::LabelLeftOfSymbol;
|
||||
case RifEclipseRftAddress::PRESSURE_P50:
|
||||
return RiuQwtSymbol::LabelAboveSymbol;
|
||||
case RifEclipseRftAddress::PRESSURE_P90:
|
||||
return RiuQwtSymbol::LabelRightOfSymbol;
|
||||
case RifEclipseRftAddress::PRESSURE_MEAN:
|
||||
return RiuQwtSymbol::LabelBelowSymbol;
|
||||
}
|
||||
return RiuQwtSymbol::LabelAboveSymbol;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellRftPlot::defineCurveColorsAndSymbols(const std::set<RiaRftPltCurveDefinition>& allCurveDefs)
|
||||
{
|
||||
m_dataSourceColors.clear();
|
||||
m_timeStepSymbols.clear();
|
||||
|
||||
std::vector<cvf::Color3f> colorTable;
|
||||
RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable);
|
||||
|
||||
std::vector<RiuQwtSymbol::PointSymbolEnum> symbolTable = {RiuQwtSymbol::SYMBOL_ELLIPSE,
|
||||
RiuQwtSymbol::SYMBOL_RECT,
|
||||
RiuQwtSymbol::SYMBOL_DIAMOND,
|
||||
RiuQwtSymbol::SYMBOL_CROSS,
|
||||
RiuQwtSymbol::SYMBOL_XCROSS,
|
||||
RiuQwtSymbol::SYMBOL_STAR1};
|
||||
|
||||
// Add new curves
|
||||
for (const RiaRftPltCurveDefinition& curveDefToAdd : allCurveDefs)
|
||||
{
|
||||
auto colorTableIndex = m_dataSourceColors.size();
|
||||
auto symbolTableIndex = m_timeStepSymbols.size();
|
||||
|
||||
RifDataSourceForRftPlt address = curveDefToAdd.address();
|
||||
|
||||
if (address.sourceType() != RifDataSourceForRftPlt::SUMMARY_RFT)
|
||||
{
|
||||
|
||||
if (!m_dataSourceColors.count(curveDefToAdd.address()))
|
||||
{
|
||||
colorTableIndex = colorTableIndex % colorTable.size();
|
||||
m_dataSourceColors[curveDefToAdd.address()] = colorTable[colorTableIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (address.sourceType() != RifDataSourceForRftPlt::ENSEMBLE_RFT)
|
||||
{
|
||||
if (!m_timeStepSymbols.count(curveDefToAdd.timeStep()))
|
||||
{
|
||||
symbolTableIndex = symbolTableIndex % symbolTable.size();
|
||||
m_timeStepSymbols[curveDefToAdd.timeStep()] = symbolTable[symbolTableIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "RimViewWindow.h"
|
||||
|
||||
#include "RifDataSourceForRftPltQMetaType.h"
|
||||
#include "RiuQwtSymbol.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
@@ -46,102 +46,118 @@ class RiuWellRftPlot;
|
||||
class RigEclipseCaseData;
|
||||
class RiaRftPltCurveDefinition;
|
||||
class RifDataSourceForRftPlt;
|
||||
class RifEclipseRftAddress;
|
||||
|
||||
namespace cvf {
|
||||
class Color3f;
|
||||
namespace cvf
|
||||
{
|
||||
class Color3f;
|
||||
}
|
||||
|
||||
namespace caf {
|
||||
class PdmOptionItemInfo;
|
||||
namespace caf
|
||||
{
|
||||
class PdmOptionItemInfo;
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimWellRftPlot : public RimViewWindow
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
static const std::set<QString> PRESSURE_DATA_NAMES;
|
||||
static const char PLOT_NAME_QFORMAT_STRING[];
|
||||
static const char PLOT_NAME_QFORMAT_STRING[];
|
||||
|
||||
public:
|
||||
RimWellRftPlot();
|
||||
~RimWellRftPlot() override;
|
||||
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
void setDescription(const QString& description);
|
||||
QString description() const;
|
||||
|
||||
QWidget* viewWidget() override;
|
||||
void zoomAll() override;
|
||||
QWidget* viewWidget() override;
|
||||
void zoomAll() override;
|
||||
|
||||
RimWellLogPlot* wellLogPlot() const;
|
||||
RimWellLogPlot* wellLogPlot() const;
|
||||
|
||||
void setSimWellOrWellPathName(const QString& currWellName);
|
||||
const QString& simWellOrWellPathName() const;
|
||||
void setSimWellOrWellPathName(const QString& currWellName);
|
||||
|
||||
int branchIndex() const;
|
||||
int branchIndex() const;
|
||||
|
||||
void applyInitialSelections();
|
||||
void applyInitialSelections();
|
||||
|
||||
static const char* plotNameFormatString();
|
||||
|
||||
protected:
|
||||
// Overridden PDM methods
|
||||
caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; }
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override;
|
||||
caf::PdmFieldHandle* userDescriptionField() override
|
||||
{
|
||||
return &m_userName;
|
||||
}
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override;
|
||||
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly) override;
|
||||
|
||||
QImage snapshotWindowContent() override;
|
||||
QImage snapshotWindowContent() override;
|
||||
|
||||
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
private:
|
||||
void calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>& options);
|
||||
void updateEditorsFromCurves();
|
||||
void updateWidgetTitleWindowTitle();
|
||||
void syncCurvesFromUiSelection();
|
||||
void assignWellPathToExtractionCurves();
|
||||
void calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>& options);
|
||||
void updateEditorsFromCurves();
|
||||
void updateWidgetTitleWindowTitle();
|
||||
void syncCurvesFromUiSelection();
|
||||
void assignWellPathToExtractionCurves();
|
||||
|
||||
std::set<RiaRftPltCurveDefinition> selectedCurveDefs() const;
|
||||
std::set<RiaRftPltCurveDefinition> curveDefsFromCurves() const;
|
||||
std::set<RiaRftPltCurveDefinition> selectedCurveDefs() const;
|
||||
std::set<RiaRftPltCurveDefinition> curveDefsFromCurves() const;
|
||||
|
||||
void updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>& allCurveDefs,
|
||||
const std::set<RiaRftPltCurveDefinition>& curveDefsToAdd,
|
||||
const std::set<RimWellLogCurve*>& curvesToDelete);
|
||||
void updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>& allCurveDefs,
|
||||
const std::set<RiaRftPltCurveDefinition>& curveDefsToAdd,
|
||||
const std::set<RimWellLogCurve*>& curvesToDelete);
|
||||
|
||||
std::vector<RifDataSourceForRftPlt> selectedSourcesExpanded() const;
|
||||
|
||||
// RimViewWindow overrides
|
||||
|
||||
QWidget* createViewWidget(QWidget* mainWindowParent) override;
|
||||
void deleteViewWidget() override;
|
||||
QWidget* createViewWidget(QWidget* mainWindowParent) override;
|
||||
void deleteViewWidget() override;
|
||||
|
||||
void applyCurveAppearance(RimWellLogCurve* newCurve);
|
||||
void applyCurveAppearance(RimWellLogCurve* newCurve);
|
||||
|
||||
void updateFormationsOnPlot() const;
|
||||
QString associatedSimWellName() const;
|
||||
void updateFormationsOnPlot() const;
|
||||
QString associatedSimWellName() const;
|
||||
|
||||
static RiuQwtSymbol::PointSymbolEnum statisticsCurveSymbolFromAddress(const RifEclipseRftAddress& address);
|
||||
static RiuQwtSymbol::LabelPosition statisticsLabelPosFromAddress(const RifEclipseRftAddress& address);
|
||||
|
||||
void defineCurveColorsAndSymbols(const std::set<RiaRftPltCurveDefinition>& allCurveDefs);
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showPlotTitle;
|
||||
caf::PdmField<QString> m_userName;
|
||||
caf::PdmField<bool> m_showPlotTitle;
|
||||
caf::PdmField<QString> m_userName;
|
||||
|
||||
caf::PdmField<QString> m_wellPathNameOrSimWellName;
|
||||
caf::PdmField<int> m_branchIndex;
|
||||
caf::PdmField<bool> m_branchDetection;
|
||||
caf::PdmField<QString> m_wellPathNameOrSimWellName;
|
||||
caf::PdmField<int> m_branchIndex;
|
||||
caf::PdmField<bool> m_branchDetection;
|
||||
caf::PdmField<bool> m_showStatisticsCurves;
|
||||
caf::PdmField<bool> m_showEnsembleCurves;
|
||||
|
||||
caf::PdmField<std::vector<RifDataSourceForRftPlt>> m_selectedSources;
|
||||
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
caf::PdmField<std::vector<RifDataSourceForRftPlt>> m_selectedSources;
|
||||
|
||||
caf::PdmChildField<RimWellLogPlot*> m_wellLogPlot;
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
|
||||
QPointer<RiuWellRftPlot> m_wellLogPlotWidget;
|
||||
caf::PdmChildField<RimWellLogPlot*> m_wellLogPlot;
|
||||
|
||||
QPointer<RiuWellRftPlot> m_wellLogPlotWidget;
|
||||
|
||||
std::map<RifDataSourceForRftPlt, cvf::Color3f> m_dataSourceColors;
|
||||
std::map<QDateTime, RiuQwtSymbol::PointSymbolEnum> m_timeStepSymbols;
|
||||
bool m_isOnLoad;
|
||||
|
||||
};
|
||||
|
||||
@@ -191,7 +191,7 @@ QList<caf::PdmOptionItemInfo> Rim3dWellLogRftCurve::calculateValueOptions(const
|
||||
if (reader)
|
||||
{
|
||||
QString dateFormat = "dd MMM yyyy";
|
||||
std::vector<QDateTime> timeStamps = reader->availableTimeSteps(wellName(), m_wellLogChannelName());
|
||||
std::set<QDateTime> timeStamps = reader->availableTimeSteps(wellName(), m_wellLogChannelName());
|
||||
for (const QDateTime& dt : timeStamps)
|
||||
{
|
||||
QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(dt, dateFormat);
|
||||
|
||||
@@ -73,12 +73,27 @@ void RimPlotCurve::PointSymbol::setUp()
|
||||
addItem(RiuQwtSymbol::SYMBOL_RECT, "SYMBOL_RECT", "Rect");
|
||||
addItem(RiuQwtSymbol::SYMBOL_DIAMOND, "SYMBOL_DIAMOND", "Diamond");
|
||||
addItem(RiuQwtSymbol::SYMBOL_TRIANGLE, "SYMBOL_TRIANGLE", "Triangle");
|
||||
addItem(RiuQwtSymbol::SYMBOL_DOWN_TRIANGLE, "SYMBOL_DOWN_TRIANGLE", "Down Triangle");
|
||||
addItem(RiuQwtSymbol::SYMBOL_CROSS, "SYMBOL_CROSS", "Cross");
|
||||
addItem(RiuQwtSymbol::SYMBOL_XCROSS, "SYMBOL_XCROSS", "X Cross");
|
||||
|
||||
addItem(RiuQwtSymbol::SYMBOL_STAR1, "SYMBOL_STAR1", "Star 1");
|
||||
addItem(RiuQwtSymbol::SYMBOL_STAR2, "SYMBOL_STAR2", "Star 2");
|
||||
addItem(RiuQwtSymbol::SYMBOL_HEXAGON, "SYMBOL_HEXAGON", "Hexagon");
|
||||
addItem(RiuQwtSymbol::SYMBOL_LEFT_TRIANGLE, "SYMBOL_LEFT_TRIANGLE", "Left Triangle");
|
||||
addItem(RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, "SYMBOL_RIGHT_TRIANGLE", "Right Triangle");
|
||||
setDefault(RiuQwtSymbol::SYMBOL_NONE);
|
||||
}
|
||||
|
||||
template<>
|
||||
void RimPlotCurve::LabelPosition::setUp()
|
||||
{
|
||||
addItem(RiuQwtSymbol::LabelAboveSymbol, "LABEL_ABOVE_SYMBOL", "Label above Symbol");
|
||||
addItem(RiuQwtSymbol::LabelBelowSymbol, "LABEL_BELOW_SYMBOL", "Label below Symbol");
|
||||
addItem(RiuQwtSymbol::LabelLeftOfSymbol, "LABEL_LEFT_OF_SYMBOL", "Label left of Symbol");
|
||||
addItem(RiuQwtSymbol::LabelRightOfSymbol, "LABEL_RIGHT_OF_SYMBOL", "Label right of Symbol");
|
||||
setDefault(RiuQwtSymbol::LabelAboveSymbol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +101,6 @@ void RimPlotCurve::PointSymbol::setUp()
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotCurve::RimPlotCurve()
|
||||
: m_symbolLabelPosition(RiuQwtSymbol::LabelAboveSymbol)
|
||||
{
|
||||
CAF_PDM_InitObject("Curve", ":/WellLogCurve16x16.png", "", "");
|
||||
|
||||
@@ -116,10 +130,13 @@ RimPlotCurve::RimPlotCurve()
|
||||
|
||||
CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Contribute To Legend", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_symbolSize, "SymbolSize", 6, "Symbol Size", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_symbolLabel, "SymbolLabel", "Symbol Label", "", "", "");
|
||||
CAF_PDM_InitField(&m_symbolSize, "SymbolSize", 6, "Symbol Size", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_showErrorBars, "ShowErrorBars", true, "Show Error Bars", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_symbolLabelPosition, "SymbolLabelPosition", "Symbol Label Position", "", "", "");
|
||||
|
||||
m_qwtPlotCurve = new RiuRimQwtPlotCurve(this);
|
||||
|
||||
m_parentQwtPlot = nullptr;
|
||||
@@ -548,7 +565,7 @@ void RimPlotCurve::updateCurveAppearance()
|
||||
if (m_pointSymbol() != RiuQwtSymbol::SYMBOL_NONE)
|
||||
{
|
||||
// QwtPlotCurve will take ownership of the symbol
|
||||
symbol = new RiuQwtSymbol(m_pointSymbol(), m_symbolLabel, m_symbolLabelPosition);
|
||||
symbol = new RiuQwtSymbol(m_pointSymbol(), m_symbolLabel(), m_symbolLabelPosition());
|
||||
symbol->setSize(m_symbolSize, m_symbolSize);
|
||||
symbol->setColor(curveColor);
|
||||
|
||||
@@ -683,6 +700,14 @@ RiuQwtSymbol::PointSymbolEnum RimPlotCurve::symbol()
|
||||
return m_pointSymbol();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimPlotCurve::symbolSize() const
|
||||
{
|
||||
return m_symbolSize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -715,6 +740,14 @@ void RimPlotCurve::setSymbolLabel(const QString& label)
|
||||
m_symbolLabel = label;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotCurve::setSymbolLabelPosition(RiuQwtSymbol::LabelPosition labelPosition)
|
||||
{
|
||||
m_symbolLabelPosition = labelPosition;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
typedef caf::AppEnum<RiuQwtPlotCurve::CurveInterpolationEnum> CurveInterpolation;
|
||||
typedef caf::AppEnum<RiuQwtPlotCurve::LineStyleEnum> LineStyle;
|
||||
typedef caf::AppEnum<RiuQwtSymbol::PointSymbolEnum> PointSymbol;
|
||||
typedef caf::AppEnum<RiuQwtSymbol::LabelPosition> LabelPosition;
|
||||
|
||||
public:
|
||||
RimPlotCurve();
|
||||
@@ -62,10 +63,12 @@ public:
|
||||
void setLineStyle(RiuQwtPlotCurve::LineStyleEnum lineStyle);
|
||||
void setSymbol(RiuQwtSymbol::PointSymbolEnum symbolStyle);
|
||||
RiuQwtSymbol::PointSymbolEnum symbol();
|
||||
int symbolSize() const;
|
||||
cvf::Color3f symbolEdgeColor() const;
|
||||
void setSymbolEdgeColor(const cvf::Color3f& edgeColor);
|
||||
void setSymbolSkipDistance(float distance);
|
||||
void setSymbolLabel(const QString& label);
|
||||
void setSymbolLabelPosition(RiuQwtSymbol::LabelPosition labelPosition);
|
||||
void setSymbolSize(int sizeInPixels);
|
||||
void setLineThickness(int thickness);
|
||||
void resetAppearance();
|
||||
@@ -128,7 +131,7 @@ protected:
|
||||
caf::PdmField<QString> m_curveName;
|
||||
caf::PdmField<QString> m_customCurveName;
|
||||
caf::PdmField<bool> m_showLegend;
|
||||
QString m_symbolLabel;
|
||||
caf::PdmField<QString> m_symbolLabel;
|
||||
caf::PdmField<int> m_symbolSize;
|
||||
caf::PdmField<QString> m_legendEntryText;
|
||||
|
||||
@@ -141,7 +144,7 @@ protected:
|
||||
caf::PdmField<PointSymbol> m_pointSymbol;
|
||||
caf::PdmField<LineStyle> m_lineStyle;
|
||||
caf::PdmField<CurveInterpolation> m_curveInterpolation;
|
||||
RiuQwtSymbol::LabelPosition m_symbolLabelPosition;
|
||||
caf::PdmField<LabelPosition> m_symbolLabelPosition;
|
||||
caf::PdmField<cvf::Color3f> m_symbolEdgeColor;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
#include "RiaSummaryTools.h"
|
||||
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
#include "RiaCurveMerger.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
@@ -267,7 +267,7 @@ bool RimSummaryCalculation::calculate()
|
||||
|
||||
std::vector<time_t> curveTimeSteps = RiaSummaryCurveDefinition::timeSteps(curveDef);
|
||||
|
||||
timeHistoryCurveMerger.addCurveData(curveValues, curveTimeSteps);
|
||||
timeHistoryCurveMerger.addCurveData(curveTimeSteps, curveValues);
|
||||
}
|
||||
|
||||
timeHistoryCurveMerger.computeInterpolatedValues();
|
||||
@@ -277,11 +277,11 @@ bool RimSummaryCalculation::calculate()
|
||||
{
|
||||
RimSummaryCalculationVariable* v = m_variables[i];
|
||||
|
||||
parser.assignVector(v->name(), timeHistoryCurveMerger.interpolatedCurveValuesForAllTimeSteps(i));
|
||||
parser.assignVector(v->name(), timeHistoryCurveMerger.interpolatedYValuesForAllXValues(i));
|
||||
}
|
||||
|
||||
std::vector<double> resultValues;
|
||||
resultValues.resize(timeHistoryCurveMerger.allTimeSteps().size());
|
||||
resultValues.resize(timeHistoryCurveMerger.allXValues().size());
|
||||
|
||||
parser.assignVector(leftHandSideVariableName, resultValues);
|
||||
|
||||
@@ -293,16 +293,16 @@ bool RimSummaryCalculation::calculate()
|
||||
m_timesteps.v().clear();
|
||||
m_calculatedValues.v().clear();
|
||||
|
||||
if (timeHistoryCurveMerger.validIntervalsForAllTimeSteps().size() > 0)
|
||||
if (timeHistoryCurveMerger.validIntervalsForAllXValues().size() > 0)
|
||||
{
|
||||
size_t firstValidTimeStep = timeHistoryCurveMerger.validIntervalsForAllTimeSteps().front().first;
|
||||
size_t lastValidTimeStep = timeHistoryCurveMerger.validIntervalsForAllTimeSteps().back().second + 1;
|
||||
size_t firstValidTimeStep = timeHistoryCurveMerger.validIntervalsForAllXValues().front().first;
|
||||
size_t lastValidTimeStep = timeHistoryCurveMerger.validIntervalsForAllXValues().back().second + 1;
|
||||
|
||||
if (lastValidTimeStep > firstValidTimeStep &&
|
||||
lastValidTimeStep <= timeHistoryCurveMerger.allTimeSteps().size())
|
||||
lastValidTimeStep <= timeHistoryCurveMerger.allXValues().size())
|
||||
{
|
||||
std::vector<time_t> validTimeSteps(timeHistoryCurveMerger.allTimeSteps().begin() + firstValidTimeStep,
|
||||
timeHistoryCurveMerger.allTimeSteps().begin() + lastValidTimeStep);
|
||||
std::vector<time_t> validTimeSteps(timeHistoryCurveMerger.allXValues().begin() + firstValidTimeStep,
|
||||
timeHistoryCurveMerger.allXValues().begin() + lastValidTimeStep);
|
||||
|
||||
|
||||
std::vector<double> validValues(resultValues.begin() + firstValidTimeStep,
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2017 Statoil ASA
|
||||
//
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "RimWellLogRftCurve.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
@@ -37,6 +36,8 @@
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogPlotCollection.h"
|
||||
@@ -60,26 +61,31 @@
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void caf::AppEnum< RifEclipseRftAddress::RftWellLogChannelType >::setUp()
|
||||
{
|
||||
addItem(RifEclipseRftAddress::NONE, "NONE", "None");
|
||||
addItem(RifEclipseRftAddress::DEPTH, "DEPTH", "Depth");
|
||||
addItem(RifEclipseRftAddress::PRESSURE, "PRESSURE", "Pressure");
|
||||
addItem(RifEclipseRftAddress::SWAT, "SWAT", "Water Saturation");
|
||||
addItem(RifEclipseRftAddress::SOIL, "SOIL", "Oil Saturation");
|
||||
addItem(RifEclipseRftAddress::SGAS, "SGAS", "Gas Saturation");
|
||||
addItem(RifEclipseRftAddress::WRAT, "WRAT", "Water Flow");
|
||||
addItem(RifEclipseRftAddress::ORAT, "ORAT", "Oil Flow");
|
||||
addItem(RifEclipseRftAddress::GRAT, "GRAT", "Gas flow");
|
||||
setDefault(RifEclipseRftAddress::NONE);
|
||||
}
|
||||
template<>
|
||||
void caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::setUp()
|
||||
{
|
||||
addItem(RifEclipseRftAddress::NONE, "NONE", "None");
|
||||
addItem(RifEclipseRftAddress::TVD, "DEPTH", "Depth");
|
||||
addItem(RifEclipseRftAddress::PRESSURE, "PRESSURE", "Pressure");
|
||||
addItem(RifEclipseRftAddress::SWAT, "SWAT", "Water Saturation");
|
||||
addItem(RifEclipseRftAddress::SOIL, "SOIL", "Oil Saturation");
|
||||
addItem(RifEclipseRftAddress::SGAS, "SGAS", "Gas Saturation");
|
||||
addItem(RifEclipseRftAddress::WRAT, "WRAT", "Water Flow");
|
||||
addItem(RifEclipseRftAddress::ORAT, "ORAT", "Oil Flow");
|
||||
addItem(RifEclipseRftAddress::GRAT, "GRAT", "Gas flow");
|
||||
addItem(RifEclipseRftAddress::MD, "MD", "Measured Depth");
|
||||
addItem(RifEclipseRftAddress::PRESSURE_P10, "PRESSURE_P10", "Pressure P10");
|
||||
addItem(RifEclipseRftAddress::PRESSURE_P50, "PRESSURE_P50", "Pressure P50");
|
||||
addItem(RifEclipseRftAddress::PRESSURE_P90, "PRESSURE_P90", "Pressure P90");
|
||||
addItem(RifEclipseRftAddress::PRESSURE_MEAN, "PRESSURE_MEAN", "Pressure Mean");
|
||||
setDefault(RifEclipseRftAddress::NONE);
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimWellLogRftCurve, "WellLogRftCurve");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellLogRftCurve::RimWellLogRftCurve()
|
||||
{
|
||||
@@ -88,12 +94,23 @@ RimWellLogRftCurve::RimWellLogRftCurve()
|
||||
CAF_PDM_InitFieldNoDefault(&m_eclipseResultCase, "CurveEclipseResultCase", "Eclipse Result Case", "", "", "");
|
||||
m_eclipseResultCase.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_summaryCase, "CurveSummaryCase", "Summary Case", "", "", "");
|
||||
m_summaryCase.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_ensemble, "CurveEnsemble", "Ensemble", "", "", "");
|
||||
m_ensemble.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_timeStep, "TimeStep", "Time Step", "", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_wellName, "WellName", "Well Name", "", "", "");
|
||||
CAF_PDM_InitField(&m_branchIndex, "BranchIndex", 0, "Branch Index", "", "", "");
|
||||
CAF_PDM_InitField(&m_branchDetection, "BranchDetection", true, "Branch Detection", "",
|
||||
"Compute branches based on how simulation well cells are organized", "");
|
||||
CAF_PDM_InitField(&m_branchDetection,
|
||||
"BranchDetection",
|
||||
true,
|
||||
"Branch Detection",
|
||||
"",
|
||||
"Compute branches based on how simulation well cells are organized",
|
||||
"");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_wellLogChannelName, "WellLogChannelName", "Well Property", "", "", "");
|
||||
|
||||
@@ -101,14 +118,12 @@ RimWellLogRftCurve::RimWellLogRftCurve()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimWellLogRftCurve::~RimWellLogRftCurve()
|
||||
{
|
||||
}
|
||||
RimWellLogRftCurve::~RimWellLogRftCurve() {}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimWellLogRftCurve::wellName() const
|
||||
{
|
||||
@@ -116,7 +131,7 @@ QString RimWellLogRftCurve::wellName() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimWellLogRftCurve::wellLogChannelName() const
|
||||
{
|
||||
@@ -124,7 +139,7 @@ QString RimWellLogRftCurve::wellLogChannelName() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setEclipseResultCase(RimEclipseResultCase* eclipseResultCase)
|
||||
{
|
||||
@@ -132,7 +147,7 @@ void RimWellLogRftCurve::setEclipseResultCase(RimEclipseResultCase* eclipseResul
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseResultCase* RimWellLogRftCurve::eclipseResultCase() const
|
||||
{
|
||||
@@ -140,12 +155,44 @@ RimEclipseResultCase* RimWellLogRftCurve::eclipseResultCase() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setSummaryCase(RimSummaryCase* summaryCase)
|
||||
{
|
||||
m_summaryCase = summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RimWellLogRftCurve::summaryCase() const
|
||||
{
|
||||
return m_summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setEnsemble(RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
m_ensemble = ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RimWellLogRftCurve::ensemble() const
|
||||
{
|
||||
return m_ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setRftAddress(RifEclipseRftAddress address)
|
||||
{
|
||||
m_timeStep = address.timeStep();
|
||||
m_wellName = address.wellName();
|
||||
m_timeStep = address.timeStep();
|
||||
m_wellName = address.wellName();
|
||||
m_wellLogChannelName = address.wellLogChannel();
|
||||
}
|
||||
|
||||
@@ -158,21 +205,21 @@ RifEclipseRftAddress RimWellLogRftCurve::rftAddress() const
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setDefaultAddress(QString wellName)
|
||||
{
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (!reader) return;
|
||||
|
||||
bool wellNameHasRftData = false;
|
||||
std::set<QString> wellNames = reader->wellNames();
|
||||
bool wellNameHasRftData = false;
|
||||
std::set<QString> wellNames = reader->wellNames();
|
||||
for (const QString& wellNameWithRft : wellNames)
|
||||
{
|
||||
if (wellName == wellNameWithRft)
|
||||
{
|
||||
wellNameHasRftData = true;
|
||||
m_wellName = wellName;
|
||||
m_wellName = wellName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -180,16 +227,16 @@ void RimWellLogRftCurve::setDefaultAddress(QString wellName)
|
||||
if (!wellNameHasRftData)
|
||||
{
|
||||
m_wellLogChannelName = RifEclipseRftAddress::NONE;
|
||||
m_timeStep = QDateTime();
|
||||
m_timeStep = QDateTime();
|
||||
return;
|
||||
}
|
||||
|
||||
m_wellLogChannelName = RifEclipseRftAddress::PRESSURE;
|
||||
|
||||
std::vector<QDateTime> timeSteps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
if (timeSteps.size() > 0)
|
||||
std::set<QDateTime> timeSteps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
if (!timeSteps.empty())
|
||||
{
|
||||
m_timeStep = timeSteps[0];
|
||||
m_timeStep = *(timeSteps.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -198,7 +245,7 @@ void RimWellLogRftCurve::setDefaultAddress(QString wellName)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::updateWellChannelNameAndTimeStep()
|
||||
{
|
||||
@@ -208,43 +255,43 @@ void RimWellLogRftCurve::updateWellChannelNameAndTimeStep()
|
||||
return;
|
||||
}
|
||||
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (!reader) return;
|
||||
|
||||
std::vector<RifEclipseRftAddress::RftWellLogChannelType> channelNames = reader->availableWellLogChannels(m_wellName);
|
||||
std::set<RifEclipseRftAddress::RftWellLogChannelType> channelNames = reader->availableWellLogChannels(m_wellName);
|
||||
|
||||
if (channelNames.empty())
|
||||
{
|
||||
m_wellLogChannelName = RifEclipseRftAddress::NONE;
|
||||
}
|
||||
else if (std::find(channelNames.begin(), channelNames.end(), m_wellLogChannelName()) == channelNames.end())
|
||||
else if (!channelNames.count(m_wellLogChannelName()))
|
||||
{
|
||||
m_wellLogChannelName = RifEclipseRftAddress::PRESSURE;
|
||||
}
|
||||
|
||||
std::vector<QDateTime> timeSteps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
std::set<QDateTime> timeSteps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
|
||||
if (timeSteps.empty())
|
||||
{
|
||||
m_timeStep = QDateTime();
|
||||
}
|
||||
else if (std::find(timeSteps.begin(), timeSteps.end(), m_timeStep()) == timeSteps.end())
|
||||
else if (!timeSteps.count(m_timeStep()))
|
||||
{
|
||||
m_timeStep = timeSteps[0];
|
||||
m_timeStep = *(timeSteps.begin());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::setSimWellBranchData(bool branchDetection, int branchIndex)
|
||||
{
|
||||
m_branchDetection = branchDetection;
|
||||
m_branchIndex = branchIndex;
|
||||
m_branchIndex = branchIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimWellLogRftCurve::createCurveAutoName()
|
||||
{
|
||||
@@ -261,12 +308,21 @@ QString RimWellLogRftCurve::createCurveAutoName()
|
||||
{
|
||||
name.push_back(m_eclipseResultCase->caseUserDescription());
|
||||
}
|
||||
else if (m_summaryCase)
|
||||
{
|
||||
name.push_back(m_summaryCase->caseName());
|
||||
}
|
||||
else if (m_ensemble)
|
||||
{
|
||||
name.push_back(m_ensemble->name());
|
||||
}
|
||||
if (wellLogChannelName() != caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::text(RifEclipseRftAddress::NONE))
|
||||
{
|
||||
RifEclipseRftAddress::RftWellLogChannelType channelNameEnum = caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::fromText(wellLogChannelName());
|
||||
{
|
||||
RifEclipseRftAddress::RftWellLogChannelType channelNameEnum =
|
||||
caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::fromText(wellLogChannelName());
|
||||
name.push_back(caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(channelNameEnum));
|
||||
}
|
||||
if ( !m_timeStep().isNull())
|
||||
if (!m_timeStep().isNull())
|
||||
{
|
||||
name.push_back(m_timeStep().toString(RiaQDateTimeTools::dateFormatString()));
|
||||
}
|
||||
@@ -275,14 +331,14 @@ QString RimWellLogRftCurve::createCurveAutoName()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
{
|
||||
this->RimPlotCurve::updateCurvePresentation(updateParentPlot);
|
||||
|
||||
m_isUsingPseudoLength = false;
|
||||
|
||||
|
||||
if (isCurveVisible())
|
||||
{
|
||||
m_curveData = new RigWellLogCurveData;
|
||||
@@ -292,18 +348,41 @@ void RimWellLogRftCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
CVF_ASSERT(wellLogPlot);
|
||||
|
||||
std::vector<double> measuredDepthVector = measuredDepthValues();
|
||||
std::vector<double> tvDepthVector = tvDepthValues();
|
||||
std::vector<double> values = xValues();
|
||||
std::vector<double> tvDepthVector = tvDepthValues();
|
||||
std::vector<double> values = xValues();
|
||||
|
||||
if (values.empty() ||
|
||||
values.size() != tvDepthVector.size() ||
|
||||
values.size() != measuredDepthVector.size())
|
||||
if (values.empty() || values.size() != tvDepthVector.size())
|
||||
{
|
||||
this->detachQwtCurve();
|
||||
return;
|
||||
}
|
||||
|
||||
m_curveData->setValuesWithTVD(values, measuredDepthVector, tvDepthVector, RiaEclipseUnitTools::depthUnit(m_eclipseResultCase->eclipseCaseData()->unitsType()), false);
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem = RiaEclipseUnitTools::UNITS_METRIC;
|
||||
if (m_eclipseResultCase)
|
||||
{
|
||||
unitSystem = m_eclipseResultCase->eclipseCaseData()->unitsType();
|
||||
}
|
||||
else if (m_summaryCase)
|
||||
{
|
||||
unitSystem = m_summaryCase->unitsSystem();
|
||||
}
|
||||
else if (m_ensemble)
|
||||
{
|
||||
unitSystem = m_ensemble->unitSystem();
|
||||
}
|
||||
else
|
||||
{
|
||||
CVF_ASSERT(false && "Need to have either an eclipse result case, a summary case or an ensemble");
|
||||
}
|
||||
|
||||
if (tvDepthVector.size() != measuredDepthVector.size())
|
||||
{
|
||||
m_isUsingPseudoLength = true;
|
||||
measuredDepthVector = tvDepthVector;
|
||||
}
|
||||
|
||||
m_curveData->setValuesWithTVD(
|
||||
values, measuredDepthVector, tvDepthVector, RiaEclipseUnitTools::depthUnit(unitSystem), false);
|
||||
|
||||
RiaDefines::DepthUnitType displayUnit = RiaDefines::UNIT_METER;
|
||||
if (wellLogPlot)
|
||||
@@ -313,11 +392,15 @@ void RimWellLogRftCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
|
||||
if (wellLogPlot->depthType() == RimWellLogPlot::MEASURED_DEPTH)
|
||||
{
|
||||
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->measuredDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
|
||||
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(),
|
||||
m_curveData->measuredDepthPlotValues(displayUnit).data(),
|
||||
static_cast<int>(m_curveData->xPlotValues().size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->trueDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
|
||||
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(),
|
||||
m_curveData->trueDepthPlotValues(displayUnit).data(),
|
||||
static_cast<int>(m_curveData->xPlotValues().size()));
|
||||
m_isUsingPseudoLength = false;
|
||||
}
|
||||
|
||||
@@ -349,7 +432,7 @@ void RimWellLogRftCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
@@ -359,10 +442,8 @@ void RimWellLogRftCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi
|
||||
curveDataGroup->add(&m_eclipseResultCase);
|
||||
curveDataGroup->add(&m_wellName);
|
||||
|
||||
RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName(curveDataGroup,
|
||||
m_wellName,
|
||||
m_branchDetection,
|
||||
m_branchIndex);
|
||||
RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName(
|
||||
curveDataGroup, m_wellName, m_branchDetection, m_branchIndex);
|
||||
|
||||
curveDataGroup->add(&m_wellLogChannelName);
|
||||
curveDataGroup->add(&m_timeStep);
|
||||
@@ -378,9 +459,10 @@ void RimWellLogRftCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
||||
QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
@@ -397,7 +479,7 @@ QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const ca
|
||||
else if (fieldNeedingOptions == &m_wellName)
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo("None", ""));
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (reader)
|
||||
{
|
||||
std::set<QString> wellNames = reader->wellNames();
|
||||
@@ -409,26 +491,29 @@ QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const ca
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_wellLogChannelName)
|
||||
{
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (reader)
|
||||
{
|
||||
for (const RifEclipseRftAddress::RftWellLogChannelType& channelName : reader->availableWellLogChannels(m_wellName))
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(channelName), channelName));
|
||||
options.push_back(caf::PdmOptionItemInfo(
|
||||
caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(channelName), channelName));
|
||||
}
|
||||
}
|
||||
if (options.empty())
|
||||
{
|
||||
options.push_back(caf::PdmOptionItemInfo(caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(RifEclipseRftAddress::NONE), RifEclipseRftAddress::NONE));
|
||||
options.push_back(caf::PdmOptionItemInfo(
|
||||
caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(RifEclipseRftAddress::NONE),
|
||||
RifEclipseRftAddress::NONE));
|
||||
}
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_timeStep)
|
||||
{
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (reader)
|
||||
{
|
||||
QString dateFormat = "dd MMM yyyy";
|
||||
std::vector<QDateTime> timeStamps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
QString dateFormat = "dd MMM yyyy";
|
||||
std::set<QDateTime> timeStamps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName());
|
||||
for (const QDateTime& dt : timeStamps)
|
||||
{
|
||||
QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(dt, dateFormat);
|
||||
@@ -441,7 +526,7 @@ QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const ca
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_branchIndex)
|
||||
{
|
||||
auto simulationWellBranches =
|
||||
auto simulationWellBranches =
|
||||
RiaSimWellBranchTools::simulationWellBranches(RimWellPlotTools::simWellName(m_wellName), m_branchDetection);
|
||||
|
||||
options = RiaSimWellBranchTools::valueOptionsForBranchIndexField(simulationWellBranches);
|
||||
@@ -451,17 +536,19 @@ QList<caf::PdmOptionItemInfo> RimWellLogRftCurve::calculateValueOptions(const ca
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
void RimWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue)
|
||||
{
|
||||
m_idxInWellPathToIdxInRftFile.clear();
|
||||
|
||||
RimWellLogCurve::fieldChangedByUi(changedField, oldValue, newValue);
|
||||
if (changedField == &m_eclipseResultCase)
|
||||
{
|
||||
m_timeStep = QDateTime();
|
||||
m_wellName = "";
|
||||
m_timeStep = QDateTime();
|
||||
m_wellName = "";
|
||||
m_wellLogChannelName = RifEclipseRftAddress::NONE;
|
||||
|
||||
this->loadDataAndUpdate(true);
|
||||
@@ -473,8 +560,7 @@ void RimWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedFiel
|
||||
updateWellChannelNameAndTimeStep();
|
||||
this->loadDataAndUpdate(true);
|
||||
}
|
||||
else if (changedField == &m_branchDetection ||
|
||||
changedField == &m_branchIndex)
|
||||
else if (changedField == &m_branchDetection || changedField == &m_branchIndex)
|
||||
{
|
||||
QString simWellName = RimWellPlotTools::simWellName(m_wellName);
|
||||
|
||||
@@ -498,24 +584,32 @@ void RimWellLogRftCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedFiel
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRft* RimWellLogRftCurve::rftReader() const
|
||||
RifReaderRftInterface* RimWellLogRftCurve::rftReader() const
|
||||
{
|
||||
if (!m_eclipseResultCase()) return nullptr;
|
||||
|
||||
return m_eclipseResultCase()->rftReader();
|
||||
if (m_eclipseResultCase())
|
||||
{
|
||||
return m_eclipseResultCase()->rftReader();
|
||||
}
|
||||
else if (m_summaryCase())
|
||||
{
|
||||
return m_summaryCase()->rftReader();
|
||||
}
|
||||
else if (m_ensemble())
|
||||
{
|
||||
return m_ensemble()->rftStatisticsReader();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigEclipseWellLogExtractor* RimWellLogRftCurve::extractor()
|
||||
{
|
||||
if (!m_eclipseResultCase()) return nullptr;
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
if (!reader) return nullptr;
|
||||
|
||||
|
||||
RimMainPlotCollection* mainPlotCollection;
|
||||
this->firstAncestorOrThisOfTypeAsserted(mainPlotCollection);
|
||||
@@ -525,13 +619,13 @@ RigEclipseWellLogExtractor* RimWellLogRftCurve::extractor()
|
||||
|
||||
RigEclipseWellLogExtractor* eclExtractor = nullptr;
|
||||
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
RimProject* proj = RiaApplication::instance()->project();
|
||||
RimWellPath* wellPath = proj->wellPathFromSimWellName(m_wellName());
|
||||
eclExtractor = wellLogCollection->findOrCreateExtractor(wellPath, m_eclipseResultCase);
|
||||
eclExtractor = wellLogCollection->findOrCreateExtractor(wellPath, m_eclipseResultCase);
|
||||
|
||||
if (!eclExtractor)
|
||||
{
|
||||
QString simWellName = RimWellPlotTools::simWellName(m_wellName);
|
||||
QString simWellName = RimWellPlotTools::simWellName(m_wellName);
|
||||
std::vector<const RigWellPath*> wellPaths = RiaSimWellBranchTools::simulationWellBranches(simWellName, m_branchDetection);
|
||||
if (wellPaths.size() == 0) return nullptr;
|
||||
|
||||
@@ -539,10 +633,8 @@ RigEclipseWellLogExtractor* RimWellLogRftCurve::extractor()
|
||||
|
||||
auto wellPathBranch = wellPaths[m_branchIndex];
|
||||
|
||||
eclExtractor = wellLogCollection->findOrCreateSimWellExtractor(simWellName,
|
||||
QString("Find or create sim well extractor"),
|
||||
wellPathBranch,
|
||||
m_eclipseResultCase->eclipseCaseData());
|
||||
eclExtractor = wellLogCollection->findOrCreateSimWellExtractor(
|
||||
simWellName, QString("Find or create sim well extractor"), wellPathBranch, m_eclipseResultCase->eclipseCaseData());
|
||||
m_isUsingPseudoLength = true;
|
||||
}
|
||||
|
||||
@@ -550,7 +642,7 @@ RigEclipseWellLogExtractor* RimWellLogRftCurve::extractor()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellLogRftCurve::createWellPathIdxToRftFileIdxMapping()
|
||||
{
|
||||
@@ -573,16 +665,19 @@ bool RimWellLogRftCurve::createWellPathIdxToRftFileIdxMapping()
|
||||
globCellIndicesToIndexInWell[intersections[idx].globCellIndex] = idx;
|
||||
}
|
||||
|
||||
RifEclipseRftAddress depthAddress(m_wellName(), m_timeStep, RifEclipseRftAddress::DEPTH);
|
||||
RifEclipseRftAddress depthAddress(m_wellName(), m_timeStep, RifEclipseRftAddress::TVD);
|
||||
std::vector<caf::VecIjk> rftIndices;
|
||||
rftReader()->cellIndices(depthAddress, &rftIndices);
|
||||
RifReaderEclipseRft* eclipseRftReader = dynamic_cast<RifReaderEclipseRft*>(rftReader());
|
||||
if (!eclipseRftReader) return false;
|
||||
|
||||
eclipseRftReader->cellIndices(depthAddress, &rftIndices);
|
||||
|
||||
const RigMainGrid* mainGrid = eclExtractor->caseData()->mainGrid();
|
||||
|
||||
for (size_t idx = 0; idx < rftIndices.size(); idx++)
|
||||
{
|
||||
caf::VecIjk ijkIndex = rftIndices[idx];
|
||||
size_t globalCellIndex = mainGrid->cellIndexFromIJK(ijkIndex.i(), ijkIndex.j(), ijkIndex.k());
|
||||
caf::VecIjk ijkIndex = rftIndices[idx];
|
||||
size_t globalCellIndex = mainGrid->cellIndexFromIJK(ijkIndex.i(), ijkIndex.j(), ijkIndex.k());
|
||||
|
||||
if (globCellIndicesToIndexInWell.find(globalCellIndex) != globCellIndicesToIndexInWell.end())
|
||||
{
|
||||
@@ -594,7 +689,7 @@ bool RimWellLogRftCurve::createWellPathIdxToRftFileIdxMapping()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimWellLogRftCurve::rftFileIndex(size_t wellPathIndex)
|
||||
{
|
||||
@@ -612,7 +707,7 @@ size_t RimWellLogRftCurve::rftFileIndex(size_t wellPathIndex)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<size_t> RimWellLogRftCurve::sortedIndicesInRftFile()
|
||||
{
|
||||
@@ -631,19 +726,19 @@ std::vector<size_t> RimWellLogRftCurve::sortedIndicesInRftFile()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimWellLogRftCurve::xValues()
|
||||
{
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
std::vector<double> values;
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
std::vector<double> values;
|
||||
|
||||
if (!reader) return values;
|
||||
|
||||
RifEclipseRftAddress address(m_wellName(), m_timeStep, m_wellLogChannelName());
|
||||
|
||||
reader->values(address, &values);
|
||||
|
||||
|
||||
bool wellPathExists = createWellPathIdxToRftFileIdxMapping();
|
||||
|
||||
if (wellPathExists)
|
||||
@@ -657,7 +752,7 @@ std::vector<double> RimWellLogRftCurve::xValues()
|
||||
valuesSorted.push_back((values.at(idx)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return valuesSorted;
|
||||
}
|
||||
else
|
||||
@@ -667,16 +762,16 @@ std::vector<double> RimWellLogRftCurve::xValues()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimWellLogRftCurve::tvDepthValues()
|
||||
{
|
||||
RifReaderEclipseRft* reader = rftReader();
|
||||
std::vector<double> values;
|
||||
RifReaderRftInterface* reader = rftReader();
|
||||
std::vector<double> values;
|
||||
|
||||
if (!reader) return values;
|
||||
|
||||
RifEclipseRftAddress depthAddress(m_wellName(), m_timeStep, RifEclipseRftAddress::DEPTH);
|
||||
RifEclipseRftAddress depthAddress(m_wellName(), m_timeStep, RifEclipseRftAddress::TVD);
|
||||
reader->values(depthAddress, &values);
|
||||
|
||||
bool wellPathExists = createWellPathIdxToRftFileIdxMapping();
|
||||
@@ -702,38 +797,37 @@ std::vector<double> RimWellLogRftCurve::tvDepthValues()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimWellLogRftCurve::measuredDepthValues()
|
||||
{
|
||||
std::vector<double> measuredDepthForCells;
|
||||
|
||||
|
||||
RigEclipseWellLogExtractor* eclExtractor = extractor();
|
||||
|
||||
if (!eclExtractor) return measuredDepthForCells;
|
||||
|
||||
std::vector<double> measuredDepthForIntersections = eclExtractor->cellIntersectionMDs();
|
||||
|
||||
|
||||
if (measuredDepthForIntersections.empty())
|
||||
{
|
||||
return measuredDepthForCells;
|
||||
}
|
||||
|
||||
std::vector< size_t> globCellIndices = eclExtractor->intersectedCellsGlobIdx();
|
||||
|
||||
std::vector<size_t> globCellIndices = eclExtractor->intersectedCellsGlobIdx();
|
||||
|
||||
for (size_t i = 0; i < globCellIndices.size() - 1; i = i + 2)
|
||||
{
|
||||
double sum = measuredDepthForIntersections[i] + measuredDepthForIntersections[i + 1];
|
||||
|
||||
measuredDepthForCells.push_back( sum / 2.0 );
|
||||
measuredDepthForCells.push_back(sum / 2.0);
|
||||
}
|
||||
|
||||
std::vector<double> measuredDepthForCellsWhichHasRftData;
|
||||
|
||||
for (size_t i = 0; i < measuredDepthForCells.size(); i++)
|
||||
{
|
||||
if(rftFileIndex(i) != cvf::UNDEFINED_SIZE_T)
|
||||
if (rftFileIndex(i) != cvf::UNDEFINED_SIZE_T)
|
||||
{
|
||||
measuredDepthForCellsWhichHasRftData.push_back(measuredDepthForCells[i]);
|
||||
}
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
class RifReaderEclipseRft;
|
||||
class RifReaderRftInterface;
|
||||
class RigEclipseWellLogExtractor;
|
||||
class RimEclipseResultCase;
|
||||
class RimSummaryCase;
|
||||
class RimSummaryCaseCollection;
|
||||
class RimWellPath;
|
||||
|
||||
//==================================================================================================
|
||||
@@ -54,6 +56,12 @@ public:
|
||||
void setEclipseResultCase(RimEclipseResultCase* eclipseResultCase);
|
||||
RimEclipseResultCase* eclipseResultCase() const;
|
||||
|
||||
void setSummaryCase(RimSummaryCase* summaryCase);
|
||||
RimSummaryCase* summaryCase() const;
|
||||
|
||||
void setEnsemble(RimSummaryCaseCollection* ensemble);
|
||||
RimSummaryCaseCollection* ensemble() const;
|
||||
|
||||
void setRftAddress(RifEclipseRftAddress address);
|
||||
RifEclipseRftAddress rftAddress() const;
|
||||
|
||||
@@ -73,7 +81,7 @@ protected:
|
||||
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
|
||||
private:
|
||||
RifReaderEclipseRft* rftReader() const;
|
||||
RifReaderRftInterface* rftReader() const;
|
||||
|
||||
RigEclipseWellLogExtractor* extractor();
|
||||
|
||||
@@ -86,11 +94,13 @@ private:
|
||||
std::vector<double> measuredDepthValues();
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimEclipseResultCase*> m_eclipseResultCase;
|
||||
caf::PdmField<QDateTime> m_timeStep;
|
||||
caf::PdmField<QString> m_wellName;
|
||||
caf::PdmField<int> m_branchIndex;
|
||||
caf::PdmField<bool> m_branchDetection;
|
||||
caf::PdmPtrField<RimEclipseResultCase*> m_eclipseResultCase;
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase;
|
||||
caf::PdmPtrField<RimSummaryCaseCollection*> m_ensemble;
|
||||
caf::PdmField<QDateTime> m_timeStep;
|
||||
caf::PdmField<QString> m_wellName;
|
||||
caf::PdmField<int> m_branchIndex;
|
||||
caf::PdmField<bool> m_branchDetection;
|
||||
|
||||
std::map<size_t, size_t> m_idxInWellPathToIdxInRftFile;
|
||||
bool m_isUsingPseudoLength;
|
||||
|
||||
@@ -110,3 +110,11 @@ RimSummaryCalculation* RifCalculatedSummaryCurveReader::findCalculationByName(co
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RifCalculatedSummaryCurveReader::unitSystem() const
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ public:
|
||||
|
||||
RimSummaryCalculation* findCalculationByName(const RifEclipseSummaryAddress& resultAddress) const;
|
||||
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const override;
|
||||
|
||||
private:
|
||||
caf::PdmPointer<RimSummaryCalculationCollection> m_calculationCollection;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaSummaryTools.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
#include "RiaCurveMerger.h"
|
||||
|
||||
#include "RifDerivedEnsembleReader.h"
|
||||
|
||||
@@ -151,14 +151,14 @@ void RimDerivedEnsembleCase::calculate(const RifEclipseSummaryAddress& address)
|
||||
reader1->values(address, &values1);
|
||||
reader2->values(address, &values2);
|
||||
|
||||
merger.addCurveData(values1, reader1->timeSteps(address));
|
||||
merger.addCurveData(values2, reader2->timeSteps(address));
|
||||
merger.addCurveData(reader1->timeSteps(address), values1);
|
||||
merger.addCurveData(reader2->timeSteps(address), values2);
|
||||
merger.computeInterpolatedValues();
|
||||
|
||||
std::vector<double>& allValues1 = merger.interpolatedCurveValuesForAllTimeSteps(0);
|
||||
std::vector<double>& allValues2 = merger.interpolatedCurveValuesForAllTimeSteps(1);
|
||||
std::vector<double>& allValues1 = merger.interpolatedYValuesForAllXValues(0);
|
||||
std::vector<double>& allValues2 = merger.interpolatedYValuesForAllXValues(1);
|
||||
|
||||
size_t sampleCount = merger.allTimeSteps().size();
|
||||
size_t sampleCount = merger.allXValues().size();
|
||||
std::vector<double> calculatedValues;
|
||||
calculatedValues.reserve(sampleCount);
|
||||
for (size_t i = 0; i < sampleCount; i++)
|
||||
@@ -174,7 +174,7 @@ void RimDerivedEnsembleCase::calculate(const RifEclipseSummaryAddress& address)
|
||||
}
|
||||
|
||||
auto& dataItem = m_data[address];
|
||||
dataItem.first = merger.allTimeSteps();
|
||||
dataItem.first = merger.allXValues();
|
||||
dataItem.second = calculatedValues;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "SummaryPlotCommands/RicNewDerivedEnsembleFeature.h"
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimEnsembleCurveFilter.h"
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "RifEnsembleStatisticsReader.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
#include "RiaTimeHistoryCurveResampler.h"
|
||||
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
@@ -173,14 +172,25 @@ void RimEnsembleStatisticsCase::calculate(const std::vector<RimSummaryCase*> sum
|
||||
}
|
||||
|
||||
double p10, p50, p90, mean;
|
||||
calculateStatistics(valuesAtTimeStep, &p10, &p50, &p90, &mean);
|
||||
RigStatisticsMath::calculateStatisticsCurves(valuesAtTimeStep, &p10, &p50, &p90, &mean);
|
||||
|
||||
if (p10 != DOUBLE_INF) m_p10Data.push_back(p10);
|
||||
if (p50 != DOUBLE_INF) m_p50Data.push_back(p50);
|
||||
if (p90 != DOUBLE_INF) m_p90Data.push_back(p90);
|
||||
if (p10 != HUGE_VAL) m_p10Data.push_back(p10);
|
||||
if (p50 != HUGE_VAL) m_p50Data.push_back(p50);
|
||||
if (p90 != HUGE_VAL) m_p90Data.push_back(p90);
|
||||
m_meanData.push_back(mean);
|
||||
}
|
||||
m_addressUsedInLastCalculation = inputAddress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RimEnsembleStatisticsCase::unitSystem() const
|
||||
{
|
||||
if (m_curveSet)
|
||||
{
|
||||
return m_curveSet->summaryCaseCollection()->unitSystem();
|
||||
}
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -193,7 +203,6 @@ void RimEnsembleStatisticsCase::clearData()
|
||||
m_p50Data.clear();
|
||||
m_p90Data.clear();
|
||||
m_meanData.clear();
|
||||
m_addressUsedInLastCalculation = RifEclipseSummaryAddress();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -239,57 +248,3 @@ std::vector<RimSummaryCase*> RimEnsembleStatisticsCase::validSummaryCases(const
|
||||
return validCases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Algorithm:
|
||||
/// https://en.wikipedia.org/wiki/Percentile#Third_variant,_'%22%60UNIQ--postMath-00000052-QINU%60%22'
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleStatisticsCase::calculateStatistics(const std::vector<double>& values, double* p10, double* p50, double* p90, double* mean)
|
||||
{
|
||||
CVF_ASSERT(p10 && p50 && p90 && mean);
|
||||
|
||||
enum PValue { P10, P50, P90 };
|
||||
|
||||
std::vector<double> sortedValues;
|
||||
double valueSum = 0;
|
||||
|
||||
{
|
||||
std::multiset<double> vSet(values.begin(), values.end());
|
||||
for (double v : vSet)
|
||||
{
|
||||
if (RiaStatisticsTools::isValidNumber(v))
|
||||
{
|
||||
sortedValues.push_back(v);
|
||||
valueSum += v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int valueCount = (int)sortedValues.size();
|
||||
double percentiles[] = { 0.1, 0.5, 0.9 };
|
||||
double pValues[] = { DOUBLE_INF, DOUBLE_INF, DOUBLE_INF };
|
||||
|
||||
for (int i = P10; i <= P90; i++)
|
||||
{
|
||||
// Check valid params
|
||||
if ((percentiles[i] < 1.0 / ((double)valueCount + 1)) || (percentiles[i] > (double)valueCount / ((double)valueCount + 1))) continue;
|
||||
|
||||
double rank = percentiles[i] * (valueCount + 1) - 1;
|
||||
double rankInt;
|
||||
double rankFrac = std::modf(rank, &rankInt);
|
||||
|
||||
if (rankInt < valueCount - 1)
|
||||
{
|
||||
pValues[i] = sortedValues[rankInt] + rankFrac * (sortedValues[rankInt + 1] - sortedValues[rankInt]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pValues[i] = sortedValues[rankInt];
|
||||
}
|
||||
}
|
||||
|
||||
*p10 = pValues[P10];
|
||||
*p50 = pValues[P50];
|
||||
*p90 = pValues[P90];
|
||||
*mean = valueSum / valueCount;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
|
||||
#include "RimSummaryCase.h"
|
||||
@@ -55,12 +56,12 @@ public:
|
||||
const RimEnsembleCurveSet* curveSet() const;
|
||||
|
||||
void calculate(const std::vector<RimSummaryCase*>& sumCases);
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const;
|
||||
|
||||
private:
|
||||
void calculate(const std::vector<RimSummaryCase*> sumCases, const RifEclipseSummaryAddress& inputAddress);
|
||||
void clearData();
|
||||
void clearData();
|
||||
std::vector<RimSummaryCase*> validSummaryCases(const std::vector<RimSummaryCase*> allSumCases, const RifEclipseSummaryAddress& inputAddress);
|
||||
void calculateStatistics(const std::vector<double>& values, double* p10, double* p50, double* p90, double* mean);
|
||||
|
||||
private:
|
||||
std::unique_ptr<RifEnsembleStatisticsReader> m_statisticsReader;
|
||||
@@ -72,5 +73,4 @@ private:
|
||||
std::vector<double> m_p90Data;
|
||||
std::vector<double> m_meanData;
|
||||
|
||||
RifEclipseSummaryAddress m_addressUsedInLastCalculation;
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "RifEclipseSummaryTools.h"
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
#include "RifReaderEclipseRft.h"
|
||||
|
||||
#include "RimTools.h"
|
||||
|
||||
@@ -42,6 +43,7 @@ CAF_PDM_SOURCE_INIT(RimFileSummaryCase,"FileSummaryCase");
|
||||
RimFileSummaryCase::RimFileSummaryCase()
|
||||
{
|
||||
CAF_PDM_InitField(&m_includeRestartFiles, "IncludeRestartFiles", false, "Include Restart Files", "", "", "");
|
||||
|
||||
m_includeRestartFiles.uiCapability()->setUiHidden(true);
|
||||
}
|
||||
|
||||
@@ -84,7 +86,12 @@ void RimFileSummaryCase::updateFilePathsFromProjectPath(const QString & newProje
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFileSummaryCase::createSummaryReaderInterface()
|
||||
{
|
||||
m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader(this->summaryHeaderFilename(), m_includeRestartFiles);
|
||||
m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader(this->summaryHeaderFilename(), m_includeRestartFiles);
|
||||
m_summaryEclipseRftReader = RimFileSummaryCase::findRftDataAndCreateReader(this->summaryHeaderFilename());
|
||||
if (m_summaryEclipseRftReader.notNull())
|
||||
{
|
||||
RiaLogging::info(QString("Found RFT Data for %1").arg(this->summaryHeaderFilename()));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -105,6 +112,26 @@ RifReaderEclipseSummary* RimFileSummaryCase::findRelatedFilesAndCreateReader(con
|
||||
return summaryFileReader;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderEclipseRft* RimFileSummaryCase::findRftDataAndCreateReader(const QString& headerFileName)
|
||||
{
|
||||
QFileInfo fileInfo(headerFileName);
|
||||
QString folder = fileInfo.absolutePath();
|
||||
|
||||
QString rftFileName = folder + "/" + fileInfo.completeBaseName() + ".RFT";
|
||||
QFileInfo rftFileInfo(rftFileName);
|
||||
|
||||
if (rftFileInfo.exists())
|
||||
{
|
||||
std::unique_ptr<RifReaderEclipseRft> rftReader(new RifReaderEclipseRft(rftFileInfo.filePath()));
|
||||
return rftReader.release();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -113,6 +140,14 @@ RifSummaryReaderInterface* RimFileSummaryCase::summaryReader()
|
||||
return m_summaryFileReader.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderRftInterface* RimFileSummaryCase::rftReader()
|
||||
{
|
||||
return m_summaryEclipseRftReader.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "cvfObject.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
class RifReaderRftInterface;
|
||||
class RifReaderEclipseRft;
|
||||
class RifReaderEclipseSummary;
|
||||
|
||||
//==================================================================================================
|
||||
@@ -42,12 +44,15 @@ public:
|
||||
|
||||
void createSummaryReaderInterface() override;
|
||||
RifSummaryReaderInterface* summaryReader() override;
|
||||
RifReaderRftInterface* rftReader() override;
|
||||
|
||||
void setIncludeRestartFiles(bool includeRestartFiles);
|
||||
|
||||
static RifReaderEclipseSummary* findRelatedFilesAndCreateReader(const QString& headerFileName, bool includeRestartFiles);
|
||||
static RifReaderEclipseSummary* findRelatedFilesAndCreateReader(const QString& headerFileName, bool includeRestartFiles);
|
||||
static RifReaderEclipseRft* findRftDataAndCreateReader(const QString& headerFileName);
|
||||
|
||||
private:
|
||||
cvf::ref<RifReaderEclipseSummary> m_summaryFileReader;
|
||||
cvf::ref<RifReaderEclipseRft> m_summaryEclipseRftReader;
|
||||
caf::PdmField<bool> m_includeRestartFiles;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
#include "RiaSummaryTools.h"
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimOilField.h"
|
||||
@@ -168,6 +169,14 @@ void RimSummaryCase::updateOptionSensitivity()
|
||||
m_shortName.uiCapability()->setUiReadOnly(m_useAutoShortName);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderRftInterface* RimSummaryCase::rftReader()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -187,6 +196,19 @@ QString RimSummaryCase::shortName() const
|
||||
return m_shortName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystemType RimSummaryCase::unitsSystem()
|
||||
{
|
||||
RifSummaryReaderInterface* reader = summaryReader();
|
||||
if (reader)
|
||||
{
|
||||
return reader->unitSystem();
|
||||
}
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RigCaseRealizationParameters.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
class RifReaderRftInterface;
|
||||
class RifSummaryReaderInterface;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
@@ -43,12 +45,15 @@ public:
|
||||
virtual QString summaryHeaderFilename() const;
|
||||
virtual QString caseName() const = 0;
|
||||
QString shortName() const;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystemType unitsSystem();
|
||||
|
||||
void updateAutoShortName();
|
||||
void updateOptionSensitivity();
|
||||
|
||||
virtual void createSummaryReaderInterface() = 0;
|
||||
virtual RifSummaryReaderInterface* summaryReader() = 0;
|
||||
virtual RifReaderRftInterface* rftReader();
|
||||
virtual QString errorMessagesFromReader() { return QString(); }
|
||||
|
||||
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) = 0;
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RifReaderEnsembleStatisticsRft.h"
|
||||
#include "RimGridSummaryCase.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
#include "RifReaderEclipseRft.h"
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
@@ -146,6 +148,8 @@ RimSummaryCaseCollection::RimSummaryCaseCollection()
|
||||
CAF_PDM_InitField(&m_isEnsemble, "IsEnsemble", false, "Is Ensemble", "", "", "");
|
||||
m_isEnsemble.uiCapability()->setUiHidden(true);
|
||||
|
||||
m_statisticsEclipseRftReader = new RifReaderEnsembleStatisticsRft(this);
|
||||
|
||||
m_commonAddressCount = 0;
|
||||
}
|
||||
|
||||
@@ -284,6 +288,50 @@ std::set<RifEclipseSummaryAddress> RimSummaryCaseCollection::ensembleSummaryAddr
|
||||
return addresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RimSummaryCaseCollection::wellsWithRftData() const
|
||||
{
|
||||
std::set<QString> allWellNames;
|
||||
for (RimSummaryCase* summaryCase : m_cases)
|
||||
{
|
||||
RifReaderRftInterface* reader = summaryCase->rftReader();
|
||||
if (reader)
|
||||
{
|
||||
std::set<QString> wellNames = reader->wellNames();
|
||||
allWellNames.insert(wellNames.begin(), wellNames.end());
|
||||
}
|
||||
}
|
||||
return allWellNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QDateTime> RimSummaryCaseCollection::rftTimeStepsForWell(const QString& wellName) const
|
||||
{
|
||||
std::set<QDateTime> allTimeSteps;
|
||||
for (RimSummaryCase* summaryCase : m_cases)
|
||||
{
|
||||
RifReaderRftInterface* reader = summaryCase->rftReader();
|
||||
if (reader)
|
||||
{
|
||||
std::set<QDateTime> timeStep = reader->availableTimeSteps(wellName);
|
||||
allTimeSteps.insert(timeStep.begin(), timeStep.end());
|
||||
}
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifReaderRftInterface* RimSummaryCaseCollection::rftStatisticsReader()
|
||||
{
|
||||
return m_statisticsEclipseRftReader.p();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -528,6 +576,18 @@ bool RimSummaryCaseCollection::operator<(const RimSummaryCaseCollection& rhs) co
|
||||
return name() < rhs.name();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaEclipseUnitTools::UnitSystem RimSummaryCaseCollection::unitSystem() const
|
||||
{
|
||||
if (m_cases.empty())
|
||||
{
|
||||
return RiaEclipseUnitTools::UNITS_UNKNOWN;
|
||||
}
|
||||
return m_cases[0]->unitsSystem();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaEclipseUnitTools.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifEclipseRftAddress.h"
|
||||
#include "RifReaderEnsembleStatisticsRft.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmField.h"
|
||||
@@ -30,6 +33,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class RifReaderRftInterface;
|
||||
class RifReaderEnsembleStatisticsRft;
|
||||
class RimSummaryCase;
|
||||
|
||||
//==================================================================================================
|
||||
@@ -87,6 +92,10 @@ public:
|
||||
bool isEnsemble() const;
|
||||
void setAsEnsemble(bool isEnsemble);
|
||||
virtual std::set<RifEclipseSummaryAddress> ensembleSummaryAddresses() const;
|
||||
std::set<QString> wellsWithRftData() const;
|
||||
std::set<QDateTime> rftTimeStepsForWell(const QString& wellName) const;
|
||||
RifReaderRftInterface* rftStatisticsReader();
|
||||
|
||||
EnsembleParameter ensembleParameter(const QString& paramName) const;
|
||||
void calculateEnsembleParametersIntersectionHash();
|
||||
void clearEnsembleParametersHashes();
|
||||
@@ -95,6 +104,8 @@ public:
|
||||
|
||||
static bool validateEnsembleCases(const std::vector<RimSummaryCase*> cases);
|
||||
bool operator<(const RimSummaryCaseCollection& rhs) const;
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem unitSystem() const;
|
||||
private:
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
QString nameAndItemCount() const;
|
||||
@@ -112,9 +123,10 @@ protected:
|
||||
caf::PdmChildArrayField<RimSummaryCase*> m_cases;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_name;
|
||||
caf::PdmProxyValueField<QString> m_nameAndItemCount;
|
||||
caf::PdmField<bool> m_isEnsemble;
|
||||
caf::PdmField<QString> m_name;
|
||||
caf::PdmProxyValueField<QString> m_nameAndItemCount;
|
||||
caf::PdmField<bool> m_isEnsemble;
|
||||
cvf::ref<RifReaderEnsembleStatisticsRft> m_statisticsEclipseRftReader;
|
||||
|
||||
size_t m_commonAddressCount; // if different address count among cases, set to 0
|
||||
};
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
|
||||
#include "RimSummaryCurve.h"
|
||||
|
||||
#include "RiaCurveMerger.h"
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaGuiApplication.h"
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
|
||||
@@ -490,14 +490,14 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
else
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.addCurveData(curveValuesX, curveTimeStepsX);
|
||||
curveMerger.addCurveData(curveValuesY, curveTimeStepsY);
|
||||
curveMerger.addCurveData(curveTimeStepsX, curveValuesX);
|
||||
curveMerger.addCurveData(curveTimeStepsY, curveValuesY);
|
||||
curveMerger.computeInterpolatedValues();
|
||||
|
||||
if (curveMerger.allTimeSteps().size() > 0)
|
||||
if (curveMerger.allXValues().size() > 0)
|
||||
{
|
||||
m_qwtPlotCurve->setSamplesFromXValuesAndYValues(curveMerger.interpolatedCurveValuesForAllTimeSteps(0),
|
||||
curveMerger.interpolatedCurveValuesForAllTimeSteps(1),
|
||||
m_qwtPlotCurve->setSamplesFromXValuesAndYValues(curveMerger.interpolatedYValuesForAllXValues(0),
|
||||
curveMerger.interpolatedYValuesForAllXValues(1),
|
||||
isLogCurve);
|
||||
}
|
||||
else
|
||||
@@ -995,11 +995,11 @@ void RimSummaryCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
|
||||
if (!curveValuesX.empty() && !curveValuesY.empty())
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.addCurveData(curveValuesX, curveTimeStepsX);
|
||||
curveMerger.addCurveData(curveValuesY, curveTimeStepsY);
|
||||
curveMerger.addCurveData(curveTimeStepsX, curveValuesX);
|
||||
curveMerger.addCurveData(curveTimeStepsY, curveValuesY);
|
||||
curveMerger.computeInterpolatedValues();
|
||||
|
||||
if (curveMerger.validIntervalsForAllTimeSteps().size() == 0)
|
||||
if (curveMerger.validIntervalsForAllXValues().size() == 0)
|
||||
{
|
||||
QString description;
|
||||
|
||||
|
||||
@@ -79,6 +79,72 @@ void RigStatisticsMath::calculateBasicStatistics(const std::vector<double>& valu
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Algorithm:
|
||||
/// https://en.wikipedia.org/wiki/Percentile#Third_variant,_'%22%60UNIQ--postMath-00000052-QINU%60%22'
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigStatisticsMath::calculateStatisticsCurves(const std::vector<double>& values,
|
||||
double* p10,
|
||||
double* p50,
|
||||
double* p90,
|
||||
double* mean)
|
||||
{
|
||||
CVF_ASSERT(p10 && p50 && p90 && mean);
|
||||
|
||||
enum PValue
|
||||
{
|
||||
P10,
|
||||
P50,
|
||||
P90
|
||||
};
|
||||
|
||||
std::vector<double> sortedValues;
|
||||
double valueSum = 0;
|
||||
|
||||
{
|
||||
std::multiset<double> vSet(values.begin(), values.end());
|
||||
for (double v : vSet)
|
||||
{
|
||||
if (RiaStatisticsTools::isValidNumber(v))
|
||||
{
|
||||
sortedValues.push_back(v);
|
||||
valueSum += v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int valueCount = (int)sortedValues.size();
|
||||
double percentiles[] = {0.1, 0.5, 0.9};
|
||||
double pValues[] = {HUGE_VAL, HUGE_VAL, HUGE_VAL};
|
||||
|
||||
for (int i = P10; i <= P90; i++)
|
||||
{
|
||||
// Check valid params
|
||||
if ((percentiles[i] < 1.0 / ((double)valueCount + 1)) || (percentiles[i] > (double)valueCount / ((double)valueCount + 1)))
|
||||
continue;
|
||||
|
||||
double rank = percentiles[i] * (valueCount + 1) - 1;
|
||||
double rankRem;
|
||||
double rankFrac = std::modf(rank, &rankRem);
|
||||
int rankInt = static_cast<int>(rankRem);
|
||||
|
||||
|
||||
if (rankInt < valueCount - 1)
|
||||
{
|
||||
pValues[i] = sortedValues[rankInt] + rankFrac * (sortedValues[rankInt + 1] - sortedValues[rankInt]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pValues[i] = sortedValues.back();
|
||||
}
|
||||
}
|
||||
|
||||
*p10 = pValues[P10];
|
||||
*p50 = pValues[P50];
|
||||
*p90 = pValues[P90];
|
||||
*mean = valueSum / valueCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Calculate the percentiles of /a inputValues at the pValPosition percentages using the "Nearest Rank"
|
||||
/// method. This method treats HUGE_VAL as "undefined" values, and ignores these. Will return HUGE_VAL if
|
||||
|
||||
@@ -28,6 +28,8 @@ class RigStatisticsMath
|
||||
{
|
||||
public:
|
||||
static void calculateBasicStatistics(const std::vector<double>& values, double* min, double* max, double* sum, double* range, double* mean, double* dev);
|
||||
static void calculateStatisticsCurves(const std::vector<double>& values, double* p10, double* p50, double* p90, double* mean);
|
||||
|
||||
static std::vector<double> calculateNearestRankPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions);
|
||||
static std::vector<double> calculateInterpolatedPercentiles(const std::vector<double> & inputValues, const std::vector<double>& pValPositions);
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ TEST(DISABLED_RifReaderEclipseRftTest, TestRifEclipseRftAddress)
|
||||
|
||||
RifReaderEclipseRft reader(filename);
|
||||
|
||||
std::vector<RifEclipseRftAddress> addresses = reader.eclipseRftAddresses();
|
||||
std::set<RifEclipseRftAddress> addresses = reader.eclipseRftAddresses();
|
||||
|
||||
/*for (RifEclipseRftAddress address : addresses)
|
||||
{
|
||||
@@ -32,7 +32,7 @@ TEST(DISABLED_RifReaderEclipseRftTest, TestRifEclipseRftAddress)
|
||||
ASSERT_TRUE(addresses.size() > 0);
|
||||
|
||||
std::vector<double> values;
|
||||
reader.values(addresses[0], &values);
|
||||
reader.values(*addresses.begin(), &values);
|
||||
ASSERT_TRUE(values.size() > 0);
|
||||
|
||||
std::cout << "First value: " << values.front() << ", last value: " << values.back() << std::endl;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
#include "RiaCurveMerger.h"
|
||||
|
||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||
|
||||
@@ -13,25 +13,25 @@ TEST(RiaTimeHistoryCurveMergerTest, TestDateInterpolation)
|
||||
std::vector<time_t> timeSteps{ 1, 5, 10, 15};
|
||||
|
||||
{
|
||||
double val = RiaTimeHistoryCurveMerger::interpolationValue(1, values, timeSteps);
|
||||
double val = RiaTimeHistoryCurveMerger::interpolatedYValue(1, timeSteps, values);
|
||||
|
||||
EXPECT_EQ(2.0, val);
|
||||
}
|
||||
|
||||
{
|
||||
double val = RiaTimeHistoryCurveMerger::interpolationValue(0, values, timeSteps);
|
||||
double val = RiaTimeHistoryCurveMerger::interpolatedYValue(0, timeSteps, values);
|
||||
|
||||
EXPECT_EQ(HUGE_VAL, val);
|
||||
}
|
||||
|
||||
{
|
||||
double val = RiaTimeHistoryCurveMerger::interpolationValue(20, values, timeSteps);
|
||||
double val = RiaTimeHistoryCurveMerger::interpolatedYValue(20, timeSteps, values);
|
||||
|
||||
EXPECT_EQ(HUGE_VAL, val);
|
||||
}
|
||||
|
||||
{
|
||||
double val = RiaTimeHistoryCurveMerger::interpolationValue(3, values, timeSteps);
|
||||
double val = RiaTimeHistoryCurveMerger::interpolatedYValue(3, timeSteps, values);
|
||||
|
||||
EXPECT_EQ(2.75, val);
|
||||
}
|
||||
@@ -54,12 +54,12 @@ TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps)
|
||||
}
|
||||
|
||||
RiaTimeHistoryCurveMerger interpolate;
|
||||
interpolate.addCurveData(valuesA, timeSteps);
|
||||
interpolate.addCurveData(valuesB, timeSteps);
|
||||
interpolate.addCurveData(timeSteps, valuesA);
|
||||
interpolate.addCurveData(timeSteps, valuesB);
|
||||
interpolate.computeInterpolatedValues();
|
||||
|
||||
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||
auto interpolatedTimeSteps = interpolate.allXValues();
|
||||
auto intervals = interpolate.validIntervalsForAllXValues();
|
||||
|
||||
EXPECT_EQ(10, static_cast<int>(interpolatedTimeSteps.size()));
|
||||
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
||||
@@ -82,12 +82,12 @@ TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete
|
||||
}
|
||||
|
||||
RiaTimeHistoryCurveMerger interpolate;
|
||||
interpolate.addCurveData(valuesA, timeSteps);
|
||||
interpolate.addCurveData(valuesB, timeSteps);
|
||||
interpolate.addCurveData(timeSteps, valuesA);
|
||||
interpolate.addCurveData(timeSteps, valuesB);
|
||||
interpolate.computeInterpolatedValues();
|
||||
|
||||
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||
auto interpolatedTimeSteps = interpolate.allXValues();
|
||||
auto intervals = interpolate.validIntervalsForAllXValues();
|
||||
|
||||
EXPECT_EQ(7, static_cast<int>(interpolatedTimeSteps.size()));
|
||||
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
||||
@@ -110,12 +110,12 @@ TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplet
|
||||
}
|
||||
|
||||
RiaTimeHistoryCurveMerger interpolate;
|
||||
interpolate.addCurveData(valuesA, timeSteps);
|
||||
interpolate.addCurveData(valuesB, timeSteps);
|
||||
interpolate.addCurveData(timeSteps, valuesA);
|
||||
interpolate.addCurveData(timeSteps, valuesB);
|
||||
interpolate.computeInterpolatedValues();
|
||||
|
||||
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||
auto interpolatedTimeSteps = interpolate.allXValues();
|
||||
auto intervals = interpolate.validIntervalsForAllXValues();
|
||||
|
||||
EXPECT_EQ(7, static_cast<int>(interpolatedTimeSteps.size()));
|
||||
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
||||
@@ -135,12 +135,13 @@ TEST(RiaTimeHistoryCurveMergerTest, OverlappintTimes)
|
||||
std::vector<time_t> timeStepsB{ 1, 2, 3, 5, 7 };
|
||||
|
||||
RiaTimeHistoryCurveMerger interpolate;
|
||||
interpolate.addCurveData(valuesA, timeStepsA);
|
||||
interpolate.addCurveData(valuesB, timeStepsB);
|
||||
interpolate.addCurveData(timeStepsA, valuesA);
|
||||
interpolate.addCurveData(timeStepsB, valuesB);
|
||||
interpolate.computeInterpolatedValues();
|
||||
EXPECT_EQ(2, static_cast<int>(interpolate.curveCount()));
|
||||
|
||||
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||
auto interpolatedTimeSteps = interpolate.allXValues();
|
||||
auto intervals = interpolate.validIntervalsForAllXValues();
|
||||
|
||||
EXPECT_EQ(10, static_cast<int>(interpolatedTimeSteps.size()));
|
||||
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
||||
@@ -154,7 +155,7 @@ TEST(RiaTimeHistoryCurveMergerTest, RobustUse)
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.computeInterpolatedValues();
|
||||
EXPECT_EQ(0, static_cast<int>(curveMerger.allTimeSteps().size()));
|
||||
EXPECT_EQ(0, static_cast<int>(curveMerger.allXValues().size()));
|
||||
}
|
||||
|
||||
std::vector<double> valuesA{ 1, 2, 3, 4, 5 };
|
||||
@@ -165,23 +166,23 @@ TEST(RiaTimeHistoryCurveMergerTest, RobustUse)
|
||||
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.addCurveData(valuesA, timeStepsA);
|
||||
curveMerger.addCurveData(timeStepsA, valuesA);
|
||||
curveMerger.computeInterpolatedValues();
|
||||
EXPECT_EQ(timeStepsA.size(), curveMerger.allTimeSteps().size());
|
||||
EXPECT_EQ(timeStepsA.size(), curveMerger.interpolatedCurveValuesForAllTimeSteps(0).size());
|
||||
EXPECT_EQ(timeStepsA.size(), curveMerger.allXValues().size());
|
||||
EXPECT_EQ(timeStepsA.size(), curveMerger.interpolatedYValuesForAllXValues(0).size());
|
||||
}
|
||||
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.addCurveData(valuesA, timeStepsA);
|
||||
curveMerger.addCurveData(valuesB, timeStepsB);
|
||||
curveMerger.addCurveData(timeStepsA, valuesA);
|
||||
curveMerger.addCurveData(timeStepsB, valuesB);
|
||||
|
||||
// Execute interpolation twice is allowed
|
||||
curveMerger.computeInterpolatedValues();
|
||||
curveMerger.computeInterpolatedValues();
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.allTimeSteps().size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedCurveValuesForAllTimeSteps(0).size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedCurveValuesForAllTimeSteps(1).size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.allXValues().size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedYValuesForAllXValues(0).size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedYValuesForAllXValues(1).size()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,13 +199,13 @@ TEST(RiaTimeHistoryCurveMergerTest, NoTimeStepOverlap)
|
||||
|
||||
{
|
||||
RiaTimeHistoryCurveMerger curveMerger;
|
||||
curveMerger.addCurveData(valuesA, timeStepsA);
|
||||
curveMerger.addCurveData(valuesB, timeStepsB);
|
||||
curveMerger.addCurveData(timeStepsA, valuesA);
|
||||
curveMerger.addCurveData(timeStepsB, valuesB);
|
||||
|
||||
// Execute interpolation twice is allowed
|
||||
curveMerger.computeInterpolatedValues();
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.allTimeSteps().size()));
|
||||
EXPECT_EQ(0, static_cast<int>(curveMerger.validIntervalsForAllTimeSteps().size()));
|
||||
EXPECT_EQ(8, static_cast<int>(curveMerger.allXValues().size()));
|
||||
EXPECT_EQ(0, static_cast<int>(curveMerger.validIntervalsForAllXValues().size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ void RiuQwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol,
|
||||
}
|
||||
|
||||
float sqSkipDist = m_symbolSkipPixelDistance * m_symbolSkipPixelDistance;
|
||||
|
||||
float sqSkipToLastDiff = m_symbolSkipPixelDistance / 10 * m_symbolSkipPixelDistance / 10;
|
||||
for (int pIdx = 1; pIdx < pointCount - 1; ++pIdx)
|
||||
{
|
||||
QPointF diff = points[pIdx] - lastDrawnSymbolPos;
|
||||
@@ -225,6 +225,13 @@ void RiuQwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol,
|
||||
|
||||
if (sqDistBetweenSymbols > sqSkipDist)
|
||||
{
|
||||
if (pIdx == pointCount - 2)
|
||||
{
|
||||
QPointF diffToBack = points.back() - points[pIdx];
|
||||
float sqDistToBack = diffToBack.x() * diffToBack.x() + diffToBack.y() * diffToBack.y();
|
||||
if (sqDistToBack < sqSkipToLastDiff)
|
||||
continue;
|
||||
}
|
||||
pointsToDisplay.push_back(points[pIdx]);
|
||||
lastDrawnSymbolPos = points[pIdx];
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ RiuQwtSymbol::RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, Label
|
||||
case SYMBOL_DOWN_TRIANGLE:
|
||||
style = QwtSymbol::DTriangle;
|
||||
break;
|
||||
case SYMBOL_LEFT_TRIANGLE:
|
||||
case SYMBOL_LEFT_ALIGNED_TRIANGLE:
|
||||
style = QwtSymbol::Path;
|
||||
{
|
||||
QPainterPath path;
|
||||
@@ -66,7 +66,7 @@ RiuQwtSymbol::RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, Label
|
||||
setPinPoint(QPointF(0, 0));
|
||||
}
|
||||
break;
|
||||
case SYMBOL_RIGHT_TRIANGLE:
|
||||
case SYMBOL_RIGHT_ALIGNED_TRIANGLE:
|
||||
style = QwtSymbol::Path;
|
||||
{
|
||||
QPainterPath path;
|
||||
@@ -114,6 +114,11 @@ RiuQwtSymbol::RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, Label
|
||||
case SYMBOL_HEXAGON:
|
||||
style = QwtSymbol::Hexagon;
|
||||
break;
|
||||
case SYMBOL_LEFT_TRIANGLE:
|
||||
style = QwtSymbol::LTriangle;
|
||||
break;
|
||||
case SYMBOL_RIGHT_TRIANGLE:
|
||||
style = QwtSymbol::RTriangle;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -132,7 +137,7 @@ void RiuQwtSymbol::renderSymbols(QPainter *painter, const QPointF *points, int n
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
{
|
||||
auto position = points[i];
|
||||
renderSymbolLabel(painter, position);
|
||||
//renderSymbolLabel(painter, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +179,6 @@ RiuQwtSymbol::PointSymbolEnum RiuQwtSymbol::cycledSymbolStyle(int indexLevel1, i
|
||||
{SYMBOL_ELLIPSE, SYMBOL_RECT, SYMBOL_DIAMOND},
|
||||
{SYMBOL_DOWN_TRIANGLE, SYMBOL_UP_TRIANGLE},
|
||||
{SYMBOL_LEFT_TRIANGLE, SYMBOL_RIGHT_TRIANGLE},
|
||||
{SYMBOL_LEFT_ANGLED_TRIANGLE, SYMBOL_RIGHT_ANGLED_TRIANGLE},
|
||||
{SYMBOL_CROSS, SYMBOL_XCROSS},
|
||||
{SYMBOL_STAR1, SYMBOL_STAR2},
|
||||
};
|
||||
@@ -208,7 +212,8 @@ QRect RiuQwtSymbol::labelBoundingRect(const QPainter* painter, const QRect& symb
|
||||
|
||||
QPoint symbolPosition = symbolRect.topLeft();
|
||||
|
||||
int symbolWidth = symbolRect.width();
|
||||
int symbolWidth = symbolRect.width();
|
||||
int symbolHeight = symbolRect.height();
|
||||
|
||||
int labelWidth = painter->fontMetrics().width(m_label);
|
||||
int labelHeight = painter->fontMetrics().height();
|
||||
@@ -218,6 +223,10 @@ QRect RiuQwtSymbol::labelBoundingRect(const QPainter* painter, const QRect& symb
|
||||
{
|
||||
labelPosition = QPoint(symbolPosition.x() - labelWidth / 2, symbolPosition.y() - 5);
|
||||
}
|
||||
else if (m_labelPosition == LabelBelowSymbol)
|
||||
{
|
||||
labelPosition = QPoint(symbolPosition.x() - labelWidth / 2, symbolPosition.y() + symbolHeight + 5);
|
||||
}
|
||||
else if (m_labelPosition == LabelLeftOfSymbol)
|
||||
{
|
||||
labelPosition = QPoint(symbolPosition.x() - labelWidth - symbolWidth, symbolPosition.y());
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
enum LabelPosition
|
||||
{
|
||||
LabelAboveSymbol,
|
||||
LabelBelowSymbol,
|
||||
LabelLeftOfSymbol,
|
||||
LabelRightOfSymbol
|
||||
};
|
||||
@@ -47,14 +48,16 @@ public:
|
||||
SYMBOL_DOWN_TRIANGLE,
|
||||
SYMBOL_CROSS,
|
||||
SYMBOL_XCROSS,
|
||||
SYMBOL_LEFT_TRIANGLE,
|
||||
SYMBOL_RIGHT_TRIANGLE,
|
||||
SYMBOL_LEFT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower right corner
|
||||
SYMBOL_RIGHT_ALIGNED_TRIANGLE, // Aligned so pin point is at lower left corner
|
||||
SYMBOL_LEFT_ANGLED_TRIANGLE,
|
||||
SYMBOL_RIGHT_ANGLED_TRIANGLE,
|
||||
SYMBOL_UP_TRIANGLE,
|
||||
SYMBOL_STAR1,
|
||||
SYMBOL_STAR2,
|
||||
SYMBOL_HEXAGON
|
||||
SYMBOL_HEXAGON,
|
||||
SYMBOL_LEFT_TRIANGLE,
|
||||
SYMBOL_RIGHT_TRIANGLE
|
||||
};
|
||||
|
||||
RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition = LabelAboveSymbol);
|
||||
|
||||
@@ -201,16 +201,16 @@ void RiuWellPathComponentPlotItem::onLoadDataAndUpdate(bool updateParentPlot)
|
||||
double markerDepth = startDepth;
|
||||
while (markerDepth < endDepth - 5)
|
||||
{
|
||||
addMarker(-casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_LEFT_TRIANGLE, componentColor());
|
||||
addMarker(casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor());
|
||||
addMarker(-casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_LEFT_ALIGNED_TRIANGLE, componentColor());
|
||||
addMarker(casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor());
|
||||
|
||||
markerDepth += markerSpacing;
|
||||
}
|
||||
addMarker(casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor(0.0), label());
|
||||
addMarker(casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor(0.0), label());
|
||||
|
||||
QwtPlotItem* legendItem1 = createMarker(16.0, 0.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor());
|
||||
QwtPlotItem* legendItem1 = createMarker(16.0, 0.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor());
|
||||
legendItem1->setLegendIconSize(QSize(4, 8));
|
||||
QwtPlotItem* legendItem2 = createMarker(16.0, 8.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor());
|
||||
QwtPlotItem* legendItem2 = createMarker(16.0, 8.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_ALIGNED_TRIANGLE, componentColor());
|
||||
legendItem2->setLegendIconSize(QSize(4, 8));
|
||||
m_combinedComponentGroup.addLegendItem(legendItem1);
|
||||
m_combinedComponentGroup.addLegendItem(legendItem2);
|
||||
|
||||
Reference in New Issue
Block a user